From b0cbe260f92182b98702604b2b726fc4a92fcc85 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 28 Mar 2013 21:34:03 -0700 Subject: [PATCH 001/303] New VO and DAO for snapshot, template and volume association table with image_data_store. --- .../storage/db/SnapshotDataStoreDao.java | 27 ++ .../storage/db/SnapshotDataStoreDaoImpl.java | 86 +++++ .../storage/db/SnapshotDataStoreVO.java | 242 ++++++++++++ .../storage/db/TemplateDataStoreDao.java | 27 ++ .../storage/db/TemplateDataStoreDaoImpl.java | 86 +++++ .../storage/db/TemplateDataStoreVO.java | 310 ++++++++++++++++ .../storage/db/VolumeDataStoreDao.java | 27 ++ .../storage/db/VolumeDataStoreDaoImpl.java | 86 +++++ .../storage/db/VolumeDataStoreVO.java | 348 ++++++++++++++++++ setup/db/db/schema-410to420.sql | 90 ++++- 10 files changed, 1323 insertions(+), 6 deletions(-) create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java create mode 100755 engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java create mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java create mode 100755 engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java new file mode 100644 index 00000000000..8a62766fa8f --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java @@ -0,0 +1,27 @@ +// 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.db; + + +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; + +public interface SnapshotDataStoreDao extends GenericDao, StateDao { + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java new file mode 100644 index 00000000000..1c291db1bd4 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java @@ -0,0 +1,86 @@ +// 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.db; +import java.util.Date; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; +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 SnapshotDataStoreDaoImpl extends GenericDaoBase implements VolumeDataStoreDao { + private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class); + private SearchBuilder updateStateSearch; + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + updateStateSearch = this.createSearchBuilder(); + updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); + updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); + updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); + updateStateSearch.done(); + return true; + } + @Override + public boolean updateState(State currentState, Event event, + State nextState, VolumeDataStoreVO dataObj, Object data) { + Long oldUpdated = dataObj.getUpdatedCount(); + Date oldUpdatedTime = dataObj.getUpdated(); + + + SearchCriteria sc = updateStateSearch.create(); + sc.setParameters("id", dataObj.getId()); + sc.setParameters("state", currentState); + sc.setParameters("updatedCount", dataObj.getUpdatedCount()); + + dataObj.incrUpdatedCount(); + + UpdateBuilder builder = getUpdateBuilder(dataObj); + builder.set(dataObj, "state", nextState); + builder.set(dataObj, "updated", new Date()); + + int rows = update(dataObj, sc); + if (rows == 0 && s_logger.isDebugEnabled()) { + VolumeDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId()); + if (dbVol != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(dataObj.toString()); + str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") + .append(dbVol.getUpdated()); + str.append(": New Data={id=").append(dataObj.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(dataObj.getUpdatedCount()) + .append("; updatedTime=").append(dataObj.getUpdated()); + str.append(": stale Data={id=").append(dataObj.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) + .append("; updatedTime=").append(oldUpdatedTime); + } else { + s_logger.debug("Unable to update objectIndatastore: id=" + dataObj.getId() + ", as there is no such object exists in the database anymore"); + } + } + return rows > 0; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java new file mode 100644 index 00000000000..527385f4be3 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java @@ -0,0 +1,242 @@ +// 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.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.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + +import com.cloud.storage.Storage; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.fsm.StateObject; + +/** + * Join table for image_data_store and snapshots + * + */ +@Entity +@Table(name="snapshot_store_ref") +public class SnapshotDataStoreVO implements StateObject, DataObjectInStore { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + Long id; + + @Column(name="store_id") + private long dataStoreId; + + @Column(name="snapshot_id") + private long snapshotId; + + @Column(name=GenericDaoBase.CREATED_COLUMN) + private Date created = null; + + @Column(name="last_updated") + @Temporal(value=TemporalType.TIMESTAMP) + private Date lastUpdated = null; + + + @Column (name="size") + private long size; + + @Column (name="physical_size") + private long physicalSize; + + + @Column (name="job_id") + private String jobId; + + @Column (name="install_path") + private String installPath; + + + @Column(name="destroyed") + boolean destroyed = false; + + @Column(name="update_count", updatable = true, nullable=false) + protected long updatedCount; + + @Column(name = "updated") + @Temporal(value = TemporalType.TIMESTAMP) + Date updated; + + @Column(name = "state") + @Enumerated(EnumType.STRING) + ObjectInDataStoreStateMachine.State state; + + public String getInstallPath() { + return installPath; + } + + public long getDataStoreId() { + return dataStoreId; + } + + public void setHostId(long hostId) { + this.dataStoreId = hostId; + } + + + public long getSnapshotId() { + return snapshotId; + } + + + public void setSnapshotId(long snapshotId) { + this.snapshotId = snapshotId; + } + + + + + 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 SnapshotDataStoreVO(long hostId, long snapshotId) { + super(); + this.dataStoreId = hostId; + this.snapshotId = snapshotId; + this.state = ObjectInDataStoreStateMachine.State.Allocated; + } + + + + protected SnapshotDataStoreVO() { + + } + + + + + public void setJobId(String jobId) { + this.jobId = jobId; + } + + + public String getJobId() { + return jobId; + } + + + public boolean equals(Object obj) { + if (obj instanceof SnapshotDataStoreVO) { + SnapshotDataStoreVO other = (SnapshotDataStoreVO)obj; + return (this.snapshotId==other.getSnapshotId() && this.dataStoreId==other.getDataStoreId()); + } + return false; + } + + + public int hashCode() { + Long tid = new Long(snapshotId); + Long hid = new Long(dataStoreId); + return tid.hashCode()+hid.hashCode(); + } + + public void setSize(long size) { + this.size = size; + } + + public long getSize() { + return size; + } + + + public void setPhysicalSize(long physicalSize) { + this.physicalSize = physicalSize; + } + + public long getPhysicalSize() { + return physicalSize; + } + + public void setDestroyed(boolean destroyed) { + this.destroyed = destroyed; + } + + public boolean getDestroyed() { + return destroyed; + } + + public long getVolumeSize() { + return -1; + } + + + public String toString() { + return new StringBuilder("VolumeHost[").append(id).append("-").append(snapshotId).append("-").append(dataStoreId).append(installPath).append("]").toString(); + } + + public long getUpdatedCount() { + return this.updatedCount; + } + + public void incrUpdatedCount() { + this.updatedCount++; + } + + public void decrUpdatedCount() { + this.updatedCount--; + } + + public Date getUpdated() { + return updated; + } + + @Override + public ObjectInDataStoreStateMachine.State getState() { + // TODO Auto-generated method stub + return this.state; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java new file mode 100644 index 00000000000..2faf3c729c9 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java @@ -0,0 +1,27 @@ +// 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.db; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; + +public interface TemplateDataStoreDao extends GenericDao, StateDao { + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java new file mode 100644 index 00000000000..c40b8ba0cd3 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java @@ -0,0 +1,86 @@ +// 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.db; +import java.util.Date; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; +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 TemplateDataStoreDaoImpl extends GenericDaoBase implements TemplateDataStoreDao { + private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class); + private SearchBuilder updateStateSearch; + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + updateStateSearch = this.createSearchBuilder(); + updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); + updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); + updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); + updateStateSearch.done(); + return true; + } + @Override + public boolean updateState(State currentState, Event event, + State nextState, TemplateDataStoreVO dataObj, Object data) { + Long oldUpdated = dataObj.getUpdatedCount(); + Date oldUpdatedTime = dataObj.getUpdated(); + + + SearchCriteria sc = updateStateSearch.create(); + sc.setParameters("id", dataObj.getId()); + sc.setParameters("state", currentState); + sc.setParameters("updatedCount", dataObj.getUpdatedCount()); + + dataObj.incrUpdatedCount(); + + UpdateBuilder builder = getUpdateBuilder(dataObj); + builder.set(dataObj, "state", nextState); + builder.set(dataObj, "updated", new Date()); + + int rows = update(dataObj, sc); + if (rows == 0 && s_logger.isDebugEnabled()) { + TemplateDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId()); + if (dbVol != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(dataObj.toString()); + str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") + .append(dbVol.getUpdated()); + str.append(": New Data={id=").append(dataObj.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(dataObj.getUpdatedCount()) + .append("; updatedTime=").append(dataObj.getUpdated()); + str.append(": stale Data={id=").append(dataObj.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) + .append("; updatedTime=").append(oldUpdatedTime); + } else { + s_logger.debug("Unable to update objectIndatastore: id=" + dataObj.getId() + ", as there is no such object exists in the database anymore"); + } + } + return rows > 0; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java new file mode 100755 index 00000000000..af393a5221d --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java @@ -0,0 +1,310 @@ +// 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.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.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; + +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.fsm.StateObject; + +/** + * Join table for image_data_store and templates + * + */ +@Entity +@Table(name="template_store_ref") +public class TemplateDataStoreVO implements StateObject, DataObjectInStore { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + Long id; + + @Column(name="store_id") + private long dataStoreId; + + @Column(name="template_id") + private long templateId; + + @Column(name=GenericDaoBase.CREATED_COLUMN) + private Date created = null; + + @Column(name="last_updated") + @Temporal(value=TemporalType.TIMESTAMP) + private Date lastUpdated = null; + + @Column (name="download_pct") + private int downloadPercent; + + @Column (name="size") + private long size; + + @Column (name="physical_size") + private long physicalSize; + + @Column (name="download_state") + @Enumerated(EnumType.STRING) + private Status downloadState; + + @Column (name="local_path") + private String localDownloadPath; + + @Column (name="error_str") + private String errorString; + + @Column (name="job_id") + private String jobId; + + @Column (name="install_path") + private String installPath; + + @Column (name="url") + private String downloadUrl; + + @Column(name="is_copy") + private boolean isCopy = false; + + @Column(name="destroyed") + boolean destroyed = false; + + @Column(name="update_count", updatable = true, nullable=false) + protected long updatedCount; + + @Column(name = "updated") + @Temporal(value = TemporalType.TIMESTAMP) + Date updated; + + @Column(name = "state") + @Enumerated(EnumType.STRING) + ObjectInDataStoreStateMachine.State state; + + + @Override + public String getInstallPath() { + return installPath; + } + + + public long getDataStoreId() { + return dataStoreId; + } + + public void setHostId(long hostId) { + this.dataStoreId = hostId; + } + + 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 TemplateDataStoreVO(long hostId, long templateId) { + super(); + this.dataStoreId = hostId; + this.templateId = templateId; + this.state = ObjectInDataStoreStateMachine.State.Allocated; + } + + public TemplateDataStoreVO(long hostId, long templateId, Date lastUpdated, + int downloadPercent, Status downloadState, + String localDownloadPath, String errorString, String jobId, + String installPath, String downloadUrl) { + super(); + this.dataStoreId = hostId; + 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.setDownloadUrl(downloadUrl); + } + + protected TemplateDataStoreVO() { + + } + + + 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; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof TemplateDataStoreVO) { + TemplateDataStoreVO other = (TemplateDataStoreVO)obj; + return (this.templateId==other.getTemplateId() && this.dataStoreId==other.getDataStoreId()); + } + return false; + } + + @Override + public int hashCode() { + Long tid = new Long(templateId); + Long hid = new Long(dataStoreId); + return tid.hashCode()+hid.hashCode(); + } + + public void setSize(long size) { + this.size = size; + } + + public long getSize() { + return size; + } + + + public void setPhysicalSize(long physicalSize) { + this.physicalSize = physicalSize; + } + + public long getPhysicalSize() { + return physicalSize; + } + + public void setDestroyed(boolean destroyed) { + this.destroyed = destroyed; + } + + public boolean getDestroyed() { + return destroyed; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setCopy(boolean isCopy) { + this.isCopy = isCopy; + } + + public boolean isCopy() { + return isCopy; + } + + public long getTemplateSize() { + return -1; + } + + @Override + public String toString() { + return new StringBuilder("TmplHost[").append(id).append("-").append(templateId).append("-").append(dataStoreId).append(installPath).append("]").toString(); + } + + @Override + public ObjectInDataStoreStateMachine.State getState() { + // TODO Auto-generated method stub + return this.state; + } + + public long getUpdatedCount() { + return this.updatedCount; + } + + public void incrUpdatedCount() { + this.updatedCount++; + } + + public void decrUpdatedCount() { + this.updatedCount--; + } + + public Date getUpdated() { + return updated; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java new file mode 100644 index 00000000000..e687d88082f --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java @@ -0,0 +1,27 @@ +// 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.db; + + +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + +import com.cloud.utils.db.GenericDao; +import com.cloud.utils.fsm.StateDao; + +public interface VolumeDataStoreDao extends GenericDao, StateDao { + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java new file mode 100644 index 00000000000..1f7b278d9bf --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java @@ -0,0 +1,86 @@ +// 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.db; +import java.util.Date; +import java.util.Map; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; +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 VolumeDataStoreDaoImpl extends GenericDaoBase implements VolumeDataStoreDao { + private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class); + private SearchBuilder updateStateSearch; + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + updateStateSearch = this.createSearchBuilder(); + updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); + updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); + updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); + updateStateSearch.done(); + return true; + } + @Override + public boolean updateState(State currentState, Event event, + State nextState, VolumeDataStoreVO dataObj, Object data) { + Long oldUpdated = dataObj.getUpdatedCount(); + Date oldUpdatedTime = dataObj.getUpdated(); + + + SearchCriteria sc = updateStateSearch.create(); + sc.setParameters("id", dataObj.getId()); + sc.setParameters("state", currentState); + sc.setParameters("updatedCount", dataObj.getUpdatedCount()); + + dataObj.incrUpdatedCount(); + + UpdateBuilder builder = getUpdateBuilder(dataObj); + builder.set(dataObj, "state", nextState); + builder.set(dataObj, "updated", new Date()); + + int rows = update(dataObj, sc); + if (rows == 0 && s_logger.isDebugEnabled()) { + VolumeDataStoreVO dbVol = findByIdIncludingRemoved(dataObj.getId()); + if (dbVol != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(dataObj.toString()); + str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") + .append(dbVol.getUpdated()); + str.append(": New Data={id=").append(dataObj.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(dataObj.getUpdatedCount()) + .append("; updatedTime=").append(dataObj.getUpdated()); + str.append(": stale Data={id=").append(dataObj.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) + .append("; updatedTime=").append(oldUpdatedTime); + } else { + s_logger.debug("Unable to update objectIndatastore: id=" + dataObj.getId() + ", as there is no such object exists in the database anymore"); + } + } + return rows > 0; + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java new file mode 100755 index 00000000000..b27a4baa902 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java @@ -0,0 +1,348 @@ +// 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.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.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + +import com.cloud.storage.Storage; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.fsm.StateObject; + +/** + * Join table for image_data_store and volumes + * + */ +@Entity +@Table(name="volume_store_ref") +public class VolumeDataStoreVO implements StateObject, DataObjectInStore { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + Long id; + + @Column(name="store_id") + private long dataStoreId; + + @Column(name="volume_id") + private long volumeId; + + @Column(name="zone_id") + private long zoneId; + + @Column(name=GenericDaoBase.CREATED_COLUMN) + private Date created = null; + + @Column(name="last_updated") + @Temporal(value=TemporalType.TIMESTAMP) + private Date lastUpdated = null; + + @Column (name="download_pct") + private int downloadPercent; + + @Column (name="size") + private long size; + + @Column (name="physical_size") + private long physicalSize; + + @Column (name="download_state") + @Enumerated(EnumType.STRING) + private Status downloadState; + + @Column(name="checksum") + private String checksum; + + @Column (name="local_path") + private String localDownloadPath; + + @Column (name="error_str") + private String errorString; + + @Column (name="job_id") + private String jobId; + + @Column (name="install_path") + private String installPath; + + @Column (name="url") + private String downloadUrl; + + @Column(name="format") + private Storage.ImageFormat format; + + @Column(name="destroyed") + boolean destroyed = false; + + @Column(name="update_count", updatable = true, nullable=false) + protected long updatedCount; + + @Column(name = "updated") + @Temporal(value = TemporalType.TIMESTAMP) + Date updated; + + @Column(name = "state") + @Enumerated(EnumType.STRING) + ObjectInDataStoreStateMachine.State state; + + public String getInstallPath() { + return installPath; + } + + public long getDataStoreId() { + return dataStoreId; + } + + public void setHostId(long hostId) { + this.dataStoreId = hostId; + } + + + public long getVolumeId() { + return volumeId; + } + + + public void setVolumeId(long volumeId) { + this.volumeId = volumeId; + } + + + public long getZoneId() { + return zoneId; + } + + public void setZoneId(long zoneId) { + this.zoneId = zoneId; + } + + 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 String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } + + public VolumeDataStoreVO(long hostId, long volumeId) { + super(); + this.dataStoreId = hostId; + this.volumeId = volumeId; + this.state = ObjectInDataStoreStateMachine.State.Allocated; + } + + public VolumeDataStoreVO(long hostId, long volumeId, long zoneId, Date lastUpdated, + int downloadPercent, Status downloadState, + String localDownloadPath, String errorString, String jobId, + String installPath, String downloadUrl, String checksum, ImageFormat format) { + //super(); + this.dataStoreId = hostId; + this.volumeId = volumeId; + this.zoneId = zoneId; + this.lastUpdated = lastUpdated; + this.downloadPercent = downloadPercent; + this.downloadState = downloadState; + this.localDownloadPath = localDownloadPath; + this.errorString = errorString; + this.jobId = jobId; + this.installPath = installPath; + this.setDownloadUrl(downloadUrl); + this.checksum = checksum; + this.format = format; + } + + protected VolumeDataStoreVO() { + + } + + + 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 boolean equals(Object obj) { + if (obj instanceof VolumeDataStoreVO) { + VolumeDataStoreVO other = (VolumeDataStoreVO)obj; + return (this.volumeId==other.getVolumeId() && this.dataStoreId==other.getDataStoreId()); + } + return false; + } + + + public int hashCode() { + Long tid = new Long(volumeId); + Long hid = new Long(dataStoreId); + return tid.hashCode()+hid.hashCode(); + } + + public void setSize(long size) { + this.size = size; + } + + public long getSize() { + return size; + } + + + public void setPhysicalSize(long physicalSize) { + this.physicalSize = physicalSize; + } + + public long getPhysicalSize() { + return physicalSize; + } + + public void setDestroyed(boolean destroyed) { + this.destroyed = destroyed; + } + + public boolean getDestroyed() { + return destroyed; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + public Storage.ImageFormat getFormat() { + return format; + } + + public void setFormat(Storage.ImageFormat format) { + this.format = format; + } + + public long getVolumeSize() { + return -1; + } + + + public String toString() { + return new StringBuilder("VolumeHost[").append(id).append("-").append(volumeId).append("-").append(dataStoreId).append(installPath).append("]").toString(); + } + + public long getUpdatedCount() { + return this.updatedCount; + } + + public void incrUpdatedCount() { + this.updatedCount++; + } + + public void decrUpdatedCount() { + this.updatedCount--; + } + + public Date getUpdated() { + return updated; + } + + @Override + public ObjectInDataStoreStateMachine.State getState() { + // TODO Auto-generated method stub + return this.state; + } + +} diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ab9df05103b..a3a756ed085 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -61,12 +61,12 @@ CREATE TABLE `cloud`.`object_datastore_ref` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`data_store_provider` ( - `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', - `name` varchar(255) NOT NULL COMMENT 'name of primary data store provider', - `uuid` varchar(255) NOT NULL COMMENT 'uuid of primary data store provider', - PRIMARY KEY(`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- CREATE TABLE `cloud`.`data_store_provider` ( +-- `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', +-- `name` varchar(255) NOT NULL COMMENT 'name of primary data store provider', +-- `uuid` varchar(255) NOT NULL COMMENT 'uuid of primary data store provider', +-- PRIMARY KEY(`id`) +-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `cloud`.`image_data_store` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', @@ -79,8 +79,86 @@ CREATE TABLE `cloud`.`image_data_store` ( PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`template_store_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `store_id` bigint unsigned NOT NULL, + `template_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `download_pct` int(10) unsigned, + `size` bigint unsigned, + `physical_size` bigint unsigned DEFAULT 0, + `download_state` varchar(255), + `error_str` varchar(255), + `local_path` varchar(255), + `install_path` varchar(255), + `url` varchar(255), + `state` varchar(255) NOT NULL, + `destroyed` tinyint(1) COMMENT 'indicates whether the template_store entry was destroyed by the user or not', + `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', + PRIMARY KEY (`id`), + CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, + INDEX `i_template_store_ref__store_id`(`store_id`), + CONSTRAINT `fk_template_store_ref__template_id` FOREIGN KEY `fk_template_store_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), + INDEX `i_template_store_ref__template_id`(`template_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + ALTER TABLE `cloud`.`vm_template` ADD COLUMN `image_data_store_id` bigint unsigned; +-- Do we still need these columns? TODO, to delete them, remove FK constraints from snapshots table +-- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `swift_id`; +-- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `s3_id`; +-- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `sechost_id`; + +CREATE TABLE `cloud`.`snapshot_store_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `store_id` bigint unsigned NOT NULL, + `snapshot_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `size` bigint unsigned, + `physical_size` bigint unsigned DEFAULT 0, + `install_path` varchar(255), + `state` varchar(255) NOT NULL, + `destroyed` tinyint(1) COMMENT 'indicates whether the snapshot_store entry was destroyed by the user or not', + PRIMARY KEY (`id`), + CONSTRAINT `fk_snapshot_store_ref__store_id` FOREIGN KEY `fk_snapshot_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, + INDEX `i_snapshot_store_ref__store_id`(`store_id`), + CONSTRAINT `fk_snapshot_store_ref__snapshot_id` FOREIGN KEY `fk_snapshot_store_ref__snapshot_id` (`snapshot_id`) REFERENCES `snapshots` (`id`), + INDEX `i_snapshot_store_ref__snapshot_id`(`snapshot_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`volume_store_ref` ( + `id` bigint unsigned NOT NULL auto_increment, + `store_id` bigint unsigned NOT NULL, + `volume_id` bigint unsigned NOT NULL, + `zone_id` bigint unsigned NOT NULL, + `created` DATETIME NOT NULL, + `last_updated` DATETIME, + `job_id` varchar(255), + `download_pct` int(10) unsigned, + `size` bigint unsigned, + `physical_size` bigint unsigned DEFAULT 0, + `download_state` varchar(255), + `checksum` varchar(255) COMMENT 'checksum for the data disk', + `error_str` varchar(255), + `local_path` varchar(255), + `install_path` varchar(255), + `url` varchar(255), + `state` varchar(255) NOT NULL, + `format` varchar(32) NOT NULL COMMENT 'format for the volume', + `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', + PRIMARY KEY (`id`), + CONSTRAINT `fk_volume_store_ref__store_id` FOREIGN KEY `fk_volume_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, + INDEX `i_volume_store_ref__store_id`(`store_id`), + CONSTRAINT `fk_volume_store_ref__volume_id` FOREIGN KEY `fk_volume_store_ref__volume_id` (`volume_id`) REFERENCES `volumes` (`id`), + INDEX `i_volume_store_ref__volume_id`(`volume_id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + + ALTER TABLE `cloud`.`service_offering` ADD COLUMN `is_volatile` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the vm needs to be volatile, i.e., on every reboot of vm from API root disk is discarded and creates a new root disk'; ALTER TABLE `cloud`.`networks` ADD COLUMN `network_cidr` VARCHAR(18) COMMENT 'The network cidr for the isolated guest network which uses IP Reservation facility.For networks not using IP reservation, network_cidr is always null.'; From a5416797ab2b3a93171e7d9ffa5832ed19988f9f Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 29 Mar 2013 16:35:13 -0700 Subject: [PATCH 002/303] Move previous AncientImageDataStore provider and DefaultImageDataStore provider code into plugins. --- .../allocator/StorageAllocatorTest.java | 4 +- .../storage/test/volumeServiceTest.java | 8 +- .../DataStoreProviderManagerImpl.java | 2 +- .../storage/volume/test/ConfiguratorTest.java | 4 +- plugins/pom.xml | 3 + plugins/storage/image/default/pom.xml | 56 +++++++++ .../CloudStackImageDataStoreDriverImpl.java | 6 +- .../CloudStackImageDataStoreLifeCycle.java | 108 ++++++++++++++++++ .../CloudStackImageDataStoreProvider.java | 16 +-- plugins/storage/image/sample/pom.xml | 56 +++++++++ .../SampleImageDataStoreDriverImpl.java | 6 +- .../SampleImageDataStoreLifeCycle.java | 7 +- .../SampleImageDataStoreProvider.java | 14 +-- ...loudStackPrimaryDataStoreProviderImpl.java | 8 +- plugins/storage/volume/sample/pom.xml | 56 +++++++++ .../SamplePrimaryDataStoreDriverImpl.java | 14 +-- .../SamplePrimaryDataStoreLifeCycleImpl.java | 4 +- .../SamplePrimaryDatastoreProviderImpl.java | 14 +-- .../SolidfirePrimaryDataStoreProvider.java | 52 +++++++-- 19 files changed, 377 insertions(+), 61 deletions(-) create mode 100644 plugins/storage/image/default/pom.xml rename engine/storage/image/src/org/apache/cloudstack/storage/image/driver/AncientImageDataStoreDriverImpl.java => plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java (97%) create mode 100644 plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java rename engine/storage/image/src/org/apache/cloudstack/storage/image/store/AncientImageDataStoreProvider.java => plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java (84%) create mode 100644 plugins/storage/image/sample/pom.xml rename engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java => plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java (96%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java => plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java (91%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreProvider.java => plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java (81%) create mode 100644 plugins/storage/volume/sample/pom.xml rename engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java => plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java (92%) rename engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java => plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java (97%) rename engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java => plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java (83%) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java index 9444fa5246e..c6ebf2e7fb5 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java @@ -121,7 +121,7 @@ public class StorageAllocatorTest { cluster = clusterDao.persist(cluster); clusterId = cluster.getId(); - DataStoreProvider provider = providerMgr.getDataStoreProvider("ancient primary data store provider"); + DataStoreProvider provider = providerMgr.getDataStoreProvider("cloudstack primary data store provider"); storage = new StoragePoolVO(); storage.setDataCenterId(dcId); storage.setPodId(podId); @@ -164,7 +164,7 @@ public class StorageAllocatorTest { try { createDb(); - DataStoreProvider provider = providerMgr.getDataStoreProvider("ancient primary data store provider"); + DataStoreProvider provider = providerMgr.getDataStoreProvider("cloudstack primary data store provider"); storage = new StoragePoolVO(); storage.setDataCenterId(dcId); storage.setPodId(podId); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 35a1790a0a9..b542e85be22 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -262,7 +262,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { @Test public void testCreatePrimaryStorage() { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default primary data store provider"); + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); Map params = new HashMap(); URI uri = null; try { @@ -290,7 +290,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { } private DataStore createImageStore() { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default image data store"); + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider"); Map params = new HashMap(); String name = UUID.randomUUID().toString(); params.put("name", name); @@ -310,7 +310,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { public DataStore createPrimaryDataStore() { try { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("default primary data store provider"); + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); Map params = new HashMap(); URI uri = new URI(this.getPrimaryStorageUrl()); params.put("url", this.getPrimaryStorageUrl()); @@ -331,7 +331,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { lifeCycle.attachCluster(store, scope); /* - PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("default primary data store provider"); + PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); primaryDataStoreProviderMgr.configure("primary data store mgr", new HashMap()); List ds = primaryStoreDao.findPoolByName(this.primaryName); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index 91b6c6329bb..f7d7167eb67 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -129,7 +129,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Override public DataStoreProvider getDefaultPrimaryDataStoreProvider() { - return this.getDataStoreProvider("ancient primary data store provider"); + return this.getDataStoreProvider("cloudstack primary data store provider"); } @Override diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java index 122c3532a09..6ad951a2e05 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java @@ -79,12 +79,12 @@ public class ConfiguratorTest { @Test public void getProvider() { - // assertNotNull(providerMgr.getDataStoreProvider("default primary data store provider")); + // assertNotNull(providerMgr.getDataStoreProvider("sample primary data store provider")); } @Test public void createDataStore() { - /*PrimaryDataStoreProvider provider = providerMgr.getDataStoreProvider("default primary data store provider"); + /*PrimaryDataStoreProvider provider = providerMgr.getDataStoreProvider("sample primary data store provider"); Map params = new HashMap(); params.put("url", "nfs://localhost/mnt"); params.put("clusterId", "1"); diff --git a/plugins/pom.xml b/plugins/pom.xml index 607c50cff22..a4f37bb1cb6 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -58,8 +58,11 @@ user-authenticators/sha256salted network-elements/dns-notifier storage/image/s3 + storage/image/default + storage/image/sample storage/volume/solidfire storage/volume/default + storage/volume/sample alert-handlers/snmp-alerts alert-handlers/syslog-alerts diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml new file mode 100644 index 00000000000..e84eab42941 --- /dev/null +++ b/plugins/storage/image/default/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + cloud-plugin-storage-image-default + Apache CloudStack Plugin - Storage Image default provider + + org.apache.cloudstack + cloudstack-plugins + 4.2.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-engine-storage-image + ${project.version} + + + mysql + mysql-connector-java + ${cs.mysql.version} + provided + + + + install + src + test + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/AncientImageDataStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java similarity index 97% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/driver/AncientImageDataStoreDriverImpl.java rename to plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java index 97ea6c48c79..1ff395cbecf 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/AncientImageDataStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.driver; +package org.apache.cloudstack.storage.datastore.driver; import java.util.List; import java.util.Set; @@ -64,9 +64,9 @@ import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.utils.exception.CloudRuntimeException; -public class AncientImageDataStoreDriverImpl implements ImageDataStoreDriver { +public class CloudStackImageDataStoreDriverImpl implements ImageDataStoreDriver { private static final Logger s_logger = Logger - .getLogger(AncientImageDataStoreDriverImpl.class); + .getLogger(CloudStackImageDataStoreDriverImpl.class); @Inject VMTemplateZoneDao templateZoneDao; @Inject diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java new file mode 100644 index 00000000000..d8965178b77 --- /dev/null +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java @@ -0,0 +1,108 @@ +// 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.datastore.lifecycle; + +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; +import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; + +import com.cloud.agent.api.StoragePoolInfo; + +public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { + @Inject + protected ImageDataStoreDao imageStoreDao; + @Inject + ImageDataStoreHelper imageStoreHelper; + @Inject + ImageDataStoreManager imageStoreMgr; + public CloudStackImageDataStoreLifeCycle() { + } + + + @Override + public DataStore initialize(Map dsInfos) { + ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(dsInfos); + return imageStoreMgr.getImageDataStore(ids.getId()); + } + + + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean attachHost(DataStore store, HostScope scope, + StoragePoolInfo existingInfo) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean attachZone(DataStore dataStore, ZoneScope scope) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean dettach() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean unmanaged() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean maintain(DataStore store) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean cancelMaintain(DataStore store) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean deleteDataStore(DataStore store) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/AncientImageDataStoreProvider.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java similarity index 84% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/AncientImageDataStoreProvider.java rename to plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java index 2715dc7e0e9..1358c9f4ca6 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/AncientImageDataStoreProvider.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.store; +package org.apache.cloudstack.storage.datastore.provider; import java.util.HashMap; import java.util.HashSet; @@ -31,20 +31,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; +import org.apache.cloudstack.storage.datastore.driver.CloudStackImageDataStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.CloudStackImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; -import org.apache.cloudstack.storage.image.driver.AncientImageDataStoreDriverImpl; -import org.apache.cloudstack.storage.image.store.lifecycle.DefaultImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; import org.springframework.stereotype.Component; import com.cloud.utils.component.ComponentContext; @Component -public class AncientImageDataStoreProvider implements ImageDataStoreProvider { +public class CloudStackImageDataStoreProvider implements ImageDataStoreProvider { - private final String name = "ancient image data store"; + private final String name = "cloudstack image data store provider"; protected ImageDataStoreLifeCycle lifeCycle; protected ImageDataStoreDriver driver; @Inject @@ -64,11 +64,11 @@ public class AncientImageDataStoreProvider implements ImageDataStoreProvider { @Override public boolean configure(Map params) { - lifeCycle = ComponentContext.inject(DefaultImageDataStoreLifeCycle.class); - driver = ComponentContext.inject(AncientImageDataStoreDriverImpl.class); + lifeCycle = ComponentContext.inject(CloudStackImageDataStoreLifeCycle.class); + driver = ComponentContext.inject(CloudStackImageDataStoreDriverImpl.class); storeMgr.registerDriver(this.getName(), driver); - + Map infos = new HashMap(); String dataStoreName = UUID.nameUUIDFromBytes(this.name.getBytes()).toString(); infos.put("name", dataStoreName); diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml new file mode 100644 index 00000000000..e4d5ac29ed8 --- /dev/null +++ b/plugins/storage/image/sample/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + cloud-plugin-storage-image-sample + Apache CloudStack Plugin - Storage Image sample provider + + org.apache.cloudstack + cloudstack-plugins + 4.2.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-engine-storage-image + ${project.version} + + + mysql + mysql-connector-java + ${cs.mysql.version} + provided + + + + install + src + test + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java similarity index 96% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java rename to plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java index 3d46c73cde2..cf42ac34da8 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/driver/DefaultImageDataStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.driver; +package org.apache.cloudstack.storage.datastore.driver; import java.util.Set; @@ -38,12 +38,12 @@ import org.apache.cloudstack.storage.image.ImageDataStoreDriver; import com.cloud.storage.dao.VMTemplateDao; //http-read-only based image store -public class DefaultImageDataStoreDriverImpl implements ImageDataStoreDriver { +public class SampleImageDataStoreDriverImpl implements ImageDataStoreDriver { @Inject EndPointSelector selector; @Inject VMTemplateDao imageDataDao; - public DefaultImageDataStoreDriverImpl() { + public SampleImageDataStoreDriverImpl() { } @Override diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java similarity index 91% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java rename to plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java index ba29c1a14b0..0af5afbb4fb 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/DefaultImageDataStoreLifeCycle.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java @@ -14,7 +14,7 @@ // 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.store.lifecycle; +package org.apache.cloudstack.storage.datastore.lifecycle; import java.util.Map; @@ -28,17 +28,18 @@ import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; import com.cloud.agent.api.StoragePoolInfo; -public class DefaultImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { +public class SampleImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { @Inject protected ImageDataStoreDao imageStoreDao; @Inject ImageDataStoreHelper imageStoreHelper; @Inject ImageDataStoreManager imageStoreMgr; - public DefaultImageDataStoreLifeCycle() { + public SampleImageDataStoreLifeCycle() { } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreProvider.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java similarity index 81% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreProvider.java rename to plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java index 0b5de858819..c6a8e0aa0ae 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreProvider.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.store; +package org.apache.cloudstack.storage.datastore.provider; import java.util.HashSet; import java.util.Map; @@ -28,16 +28,16 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; +import org.apache.cloudstack.storage.datastore.driver.SampleImageDataStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.SampleImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; -import org.apache.cloudstack.storage.image.driver.DefaultImageDataStoreDriverImpl; -import org.apache.cloudstack.storage.image.store.lifecycle.DefaultImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; import com.cloud.utils.component.ComponentContext; -public class DefaultImageDataStoreProvider implements ImageDataStoreProvider { - private final String name = "default image data store"; +public class SampleImageDataStoreProvider implements ImageDataStoreProvider { + private final String name = "sample image data store provider"; protected ImageDataStoreLifeCycle lifeCycle; protected ImageDataStoreDriver driver; @Inject @@ -56,8 +56,8 @@ public class DefaultImageDataStoreProvider implements ImageDataStoreProvider { @Override public boolean configure(Map params) { - lifeCycle = ComponentContext.inject(DefaultImageDataStoreLifeCycle.class); - driver = ComponentContext.inject(DefaultImageDataStoreDriverImpl.class); + lifeCycle = ComponentContext.inject(SampleImageDataStoreLifeCycle.class); + driver = ComponentContext.inject(SampleImageDataStoreDriverImpl.class); storeMgr.registerDriver(this.getName(), driver); return true; diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java index 4d46d99fab3..af1d0c42df3 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java @@ -34,15 +34,15 @@ import com.cloud.utils.component.ComponentContext; public class CloudStackPrimaryDataStoreProviderImpl implements PrimaryDataStoreProvider { - private final String providerName = "ancient primary data store provider"; + private final String providerName = "cloudstack primary data store provider"; protected PrimaryDataStoreDriver driver; protected HypervisorHostListener listener; protected DataStoreLifeCycle lifecyle; CloudStackPrimaryDataStoreProviderImpl() { - + } - + @Override public String getName() { return providerName; @@ -70,7 +70,7 @@ public class CloudStackPrimaryDataStoreProviderImpl implements public HypervisorHostListener getHostListener() { return this.listener; } - + @Override public Set getTypes() { Set types = new HashSet(); diff --git a/plugins/storage/volume/sample/pom.xml b/plugins/storage/volume/sample/pom.xml new file mode 100644 index 00000000000..2e2fdb51806 --- /dev/null +++ b/plugins/storage/volume/sample/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + cloud-plugin-storage-volume-sample + Apache CloudStack Plugin - Storage Volume sample provider + + org.apache.cloudstack + cloudstack-plugins + 4.2.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + mysql + mysql-connector-java + ${cs.mysql.version} + provided + + + + install + src + test + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java similarity index 92% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java rename to plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index 6d0c2c6862b..67e9843c037 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/DefaultPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -46,15 +46,15 @@ import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.Decoder; -public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { - private static final Logger s_logger = Logger.getLogger(DefaultPrimaryDataStoreDriverImpl.class); +public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { + private static final Logger s_logger = Logger.getLogger(SamplePrimaryDataStoreDriverImpl.class); @Inject EndPointSelector selector; @Inject StoragePoolHostDao storeHostDao; @Inject DataObjectManager dataObjMgr; - public DefaultPrimaryDataStoreDriverImpl() { + public SamplePrimaryDataStoreDriverImpl() { } @@ -74,7 +74,7 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver } - public Void createAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + public Void createAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = null; CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult()) { @@ -94,13 +94,13 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver EndPoint ep = selector.select(vo); AsyncRpcConext context = new AsyncRpcConext(callback); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().deleteCallback(null, null)) .setContext(context); ep.sendMessageAsync(cmd, caller); } - public Void deleteCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { + public Void deleteCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { CommandResult result = new CommandResult(); Answer answer = callback.getResult(); if (!answer.getResult()) { @@ -165,7 +165,7 @@ public class DefaultPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver CreateObjectCommand createCmd = new CreateObjectCommand(vol.getUri()); CreateVolumeContext context = new CreateVolumeContext(callback, vol); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context) .setCallback(caller.getTarget().createAsyncCallback(null, null)); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java similarity index 97% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java rename to plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java index fea02e8d1ed..15bf8c1dc06 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/lifecycle/DefaultPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java @@ -43,7 +43,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePoolStatus; -public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle { +public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle { @Inject EndPointSelector selector; @Inject @@ -54,7 +54,7 @@ public class DefaultPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLif PrimaryDataStoreHelper primaryStoreHelper; @Inject PrimaryDataStoreProviderManager providerMgr; - public DefaultPrimaryDataStoreLifeCycleImpl() { + public SamplePrimaryDataStoreLifeCycleImpl() { } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java similarity index 83% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java rename to plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java index 46fa738e294..8f6cb1bfa55 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultPrimaryDatastoreProviderImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java @@ -29,14 +29,14 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider.DataStoreProviderType; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.datastore.driver.DefaultPrimaryDataStoreDriverImpl; -import org.apache.cloudstack.storage.datastore.lifecycle.DefaultPrimaryDataStoreLifeCycleImpl; +import org.apache.cloudstack.storage.datastore.driver.SamplePrimaryDataStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.SamplePrimaryDataStoreLifeCycleImpl; import com.cloud.utils.component.ComponentContext; -public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider { - private final String providerName = "default primary data store provider"; +public class SamplePrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider { + private final String providerName = "sample primary data store provider"; protected PrimaryDataStoreDriver driver; protected HypervisorHostListener listener; @Inject @@ -57,8 +57,8 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv @Override public boolean configure(Map params) { - lifecyle = ComponentContext.inject(DefaultPrimaryDataStoreLifeCycleImpl.class); - driver = ComponentContext.inject(DefaultPrimaryDataStoreDriverImpl.class); + lifecyle = ComponentContext.inject(SamplePrimaryDataStoreLifeCycleImpl.class); + driver = ComponentContext.inject(SamplePrimaryDataStoreDriverImpl.class); listener = ComponentContext.inject(DefaultHostListener.class); return true; } @@ -72,7 +72,7 @@ public class DefaultPrimaryDatastoreProviderImpl implements PrimaryDataStoreProv public HypervisorHostListener getHostListener() { return this.listener; } - + @Override public Set getTypes() { Set types = new HashSet(); diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java index 650cac8518d..39adf9f1075 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java @@ -16,24 +16,60 @@ // under the License. package org.apache.cloudstack.storage.datastore.provider; +import java.util.Map; +import java.util.Set; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.springframework.stereotype.Component; @Component -public class SolidfirePrimaryDataStoreProvider extends - DefaultPrimaryDatastoreProviderImpl { - private final String name = "Solidfre Primary Data Store Provider"; +public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvider { + private final String name = "Solidfire Primary Data Store Provider"; public SolidfirePrimaryDataStoreProvider() { - - + + // TODO Auto-generated constructor stub } - + @Override public String getName() { return name; } - - + + @Override + public DataStoreLifeCycle getDataStoreLifeCycle() { + // TODO Auto-generated method stub + return null; + } + + @Override + public DataStoreDriver getDataStoreDriver() { + // TODO Auto-generated method stub + return null; + } + + @Override + public HypervisorHostListener getHostListener() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean configure(Map params) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Set getTypes() { + // TODO Auto-generated method stub + return null; + } + + } From 5b31a45ebca0a6c475348f387080d2888879ea5f Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 29 Mar 2013 17:22:54 -0700 Subject: [PATCH 003/303] Some further naming refactoring. --- client/tomcatconf/applicationContext.xml.in | 2 +- ...=> ImageDataStoreProviderManagerImpl.java} | 8 ++++---- ...StoreImpl.java => ImageDataStoreImpl.java} | 6 +++--- .../datastore/DataStoreManagerImpl.java | 4 ++-- .../DataStoreProviderManagerImpl.java | 19 +++++++++++++------ ...ava => ImageDataStoreProviderManager.java} | 2 +- ...taStore.java => PrimaryDataStoreImpl.java} | 10 +++++----- ... PrimaryDataStoreProviderManagerImpl.java} | 6 +++--- .../PrimaryDataStoreProviderManager.java | 16 ---------------- .../CloudStackImageDataStoreLifeCycle.java | 4 ++-- .../CloudStackImageDataStoreProvider.java | 4 ++-- .../SampleImageDataStoreLifeCycle.java | 4 ++-- .../SampleImageDataStoreProvider.java | 4 ++-- 13 files changed, 40 insertions(+), 49 deletions(-) rename engine/storage/image/src/org/apache/cloudstack/storage/image/manager/{ImageDataStoreManagerImpl.java => ImageDataStoreProviderManagerImpl.java} (92%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/store/{DefaultImageDataStoreImpl.java => ImageDataStoreImpl.java} (95%) rename engine/storage/src/org/apache/cloudstack/storage/image/datastore/{ImageDataStoreManager.java => ImageDataStoreProviderManager.java} (96%) rename engine/storage/volume/src/org/apache/cloudstack/storage/datastore/{DefaultPrimaryDataStore.java => PrimaryDataStoreImpl.java} (96%) rename engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/{DefaultPrimaryDataStoreProviderManagerImpl.java => PrimaryDataStoreProviderManagerImpl.java} (90%) delete mode 100644 engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 0b4ba82f630..7b752f0b08a 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -731,7 +731,7 @@ - + diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreProviderManagerImpl.java similarity index 92% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreManagerImpl.java rename to engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreProviderManagerImpl.java index bc546f8d0c1..4430267c700 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreProviderManagerImpl.java @@ -31,16 +31,16 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageDataStore; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; -import org.apache.cloudstack.storage.image.store.DefaultImageDataStoreImpl; +import org.apache.cloudstack.storage.image.store.ImageDataStoreImpl; import org.springframework.stereotype.Component; import com.cloud.storage.dao.VMTemplateDao; @Component -public class ImageDataStoreManagerImpl implements ImageDataStoreManager { +public class ImageDataStoreProviderManagerImpl implements ImageDataStoreProviderManager { @Inject ImageDataStoreDao dataStoreDao; @Inject @@ -59,7 +59,7 @@ public class ImageDataStoreManagerImpl implements ImageDataStoreManager { ImageDataStoreVO dataStore = dataStoreDao.findById(dataStoreId); String providerName = dataStore.getProviderName(); ImageDataStoreProvider provider = (ImageDataStoreProvider)providerManager.getDataStoreProvider(providerName); - ImageDataStore imgStore = DefaultImageDataStoreImpl.getDataStore(dataStore, + ImageDataStore imgStore = ImageDataStoreImpl.getDataStore(dataStore, driverMaps.get(provider.getName()), provider ); // TODO Auto-generated method stub diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java similarity index 95% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreImpl.java rename to engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java index 6eefc6f43f8..5761033c351 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/DefaultImageDataStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java @@ -41,7 +41,7 @@ import com.cloud.utils.component.ComponentContext; import com.cloud.utils.storage.encoding.EncodingType; -public class DefaultImageDataStoreImpl implements ImageDataStore { +public class ImageDataStoreImpl implements ImageDataStore { @Inject VMTemplateDao imageDao; @Inject @@ -51,7 +51,7 @@ public class DefaultImageDataStoreImpl implements ImageDataStore { protected ImageDataStoreProvider provider; boolean needDownloadToCacheStorage = false; - public DefaultImageDataStoreImpl() { + public ImageDataStoreImpl() { } @@ -64,7 +64,7 @@ public class DefaultImageDataStoreImpl implements ImageDataStore { public static ImageDataStore getDataStore(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, ImageDataStoreProvider provider) { - DefaultImageDataStoreImpl instance = (DefaultImageDataStoreImpl)ComponentContext.inject(DefaultImageDataStoreImpl.class); + ImageDataStoreImpl instance = (ImageDataStoreImpl)ComponentContext.inject(ImageDataStoreImpl.class); instance.configure(dataStoreVO, imageDataStoreDriver, provider); return instance; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index a2fd08d1e8f..80e48a2d8f1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -27,7 +27,7 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.springframework.stereotype.Component; import com.cloud.utils.exception.CloudRuntimeException; @@ -37,7 +37,7 @@ public class DataStoreManagerImpl implements DataStoreManager { @Inject PrimaryDataStoreProviderManager primaryStorMgr; @Inject - ImageDataStoreManager imageDataStoreMgr; + ImageDataStoreProviderManager imageDataStoreMgr; @Override public DataStore getDataStore(long storeId, DataStoreRole role) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index f7d7167eb67..c6911df31d3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -34,8 +34,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; +import org.apache.cloudstack.storage.image.ImageDataStoreDriver; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -53,6 +55,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto protected Map providerMap = new HashMap(); @Inject PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; + @Inject + ImageDataStoreProviderManager imageDataStoreProviderMgr; @Override public DataStoreProvider getDataStoreProvider(String name) { return providerMap.get(name); @@ -63,7 +67,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto // TODO Auto-generated method stub return null; } - + public List getPrimayrDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { @@ -76,7 +80,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } return providers; } - + public List getImageDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { @@ -101,9 +105,9 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto s_logger.debug("Failed to register data store provider, provider name: " + providerName + " is not unique"); return false; } - + s_logger.debug("registering data store provider:" + provider.getName()); - + providerMap.put(providerName, provider); try { boolean registrationResult = provider.configure(copyParams); @@ -112,18 +116,21 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto s_logger.debug("Failed to register data store provider: " + providerName); return false; } - + Set types = provider.getTypes(); if (types.contains(DataStoreProviderType.PRIMARY)) { primaryDataStoreProviderMgr.registerDriver(provider.getName(), (PrimaryDataStoreDriver)provider.getDataStoreDriver()); primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener()); } + else if (types.contains(DataStoreProviderType.IMAGE)) { + imageDataStoreProviderMgr.registerDriver(provider.getName(), (ImageDataStoreDriver)provider.getDataStoreDriver()); + } } catch(Exception e) { s_logger.debug("configure provider failed", e); providerMap.remove(providerName); } } - + return true; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreProviderManager.java similarity index 96% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreManager.java rename to engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreProviderManager.java index b6d84cdcef2..4ab3f3c19d8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreProviderManager.java @@ -23,7 +23,7 @@ import java.util.List; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -public interface ImageDataStoreManager { +public interface ImageDataStoreProviderManager { ImageDataStore getImageDataStore(long dataStoreId); ImageDataStore getImageDataStore(String uuid); List getList(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java similarity index 96% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java rename to engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 31e6908e28f..b695ff09c2e 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/DefaultPrimaryDataStore.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -60,9 +60,9 @@ import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.EncodingType; -public class DefaultPrimaryDataStore implements PrimaryDataStore { +public class PrimaryDataStoreImpl implements PrimaryDataStore { private static final Logger s_logger = Logger - .getLogger(DefaultPrimaryDataStore.class); + .getLogger(PrimaryDataStoreImpl.class); protected PrimaryDataStoreDriver driver; protected StoragePoolVO pdsv; @Inject @@ -82,7 +82,7 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { private VolumeDao volumeDao; - public DefaultPrimaryDataStore() { + public PrimaryDataStoreImpl() { } @@ -93,10 +93,10 @@ public class DefaultPrimaryDataStore implements PrimaryDataStore { this.provider = provider; } - public static DefaultPrimaryDataStore createDataStore( + public static PrimaryDataStoreImpl createDataStore( StoragePoolVO pdsv, PrimaryDataStoreDriver driver, DataStoreProvider provider) { - DefaultPrimaryDataStore dataStore = (DefaultPrimaryDataStore)ComponentContext.inject(DefaultPrimaryDataStore.class); + PrimaryDataStoreImpl dataStore = (PrimaryDataStoreImpl)ComponentContext.inject(PrimaryDataStoreImpl.class); dataStore.configure(pdsv, driver, provider); return dataStore; } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java similarity index 90% rename from engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java rename to engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java index e38c3b306fa..7a5d3224444 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/DefaultPrimaryDataStoreProviderManagerImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java @@ -28,7 +28,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -import org.apache.cloudstack.storage.datastore.DefaultPrimaryDataStore; +import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; @@ -39,7 +39,7 @@ import org.springframework.stereotype.Component; import com.cloud.storage.StorageManager; @Component -public class DefaultPrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager { +public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager { @Inject DataStoreProviderDao dataStoreProviderDao; @Inject @@ -59,7 +59,7 @@ public class DefaultPrimaryDataStoreProviderManagerImpl implements PrimaryDataSt StoragePoolVO dataStoreVO = dataStoreDao.findById(dataStoreId); String providerName = dataStoreVO.getStorageProviderName(); DataStoreProvider provider = providerManager.getDataStoreProvider(providerName); - DefaultPrimaryDataStore dataStore = DefaultPrimaryDataStore.createDataStore(dataStoreVO, driverMaps.get(provider.getName()), provider); + PrimaryDataStoreImpl dataStore = PrimaryDataStoreImpl.createDataStore(dataStoreVO, driverMaps.get(provider.getName()), provider); return dataStore; } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java deleted file mode 100644 index b248758bc12..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/PrimaryDataStoreProviderManager.java +++ /dev/null @@ -1,16 +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. diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java index d8965178b77..dce40d97dbc 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java @@ -25,7 +25,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; @@ -38,7 +38,7 @@ public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycl @Inject ImageDataStoreHelper imageStoreHelper; @Inject - ImageDataStoreManager imageStoreMgr; + ImageDataStoreProviderManager imageStoreMgr; public CloudStackImageDataStoreLifeCycle() { } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java index 1358c9f4ca6..c91aa1e3af2 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java @@ -35,7 +35,7 @@ import org.apache.cloudstack.storage.datastore.driver.CloudStackImageDataStoreDr import org.apache.cloudstack.storage.datastore.lifecycle.CloudStackImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; import org.springframework.stereotype.Component; @@ -48,7 +48,7 @@ public class CloudStackImageDataStoreProvider implements ImageDataStoreProvider protected ImageDataStoreLifeCycle lifeCycle; protected ImageDataStoreDriver driver; @Inject - ImageDataStoreManager storeMgr; + ImageDataStoreProviderManager storeMgr; @Inject ImageDataStoreHelper helper; diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java index 0af5afbb4fb..c1e08912718 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java @@ -25,7 +25,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; @@ -38,7 +38,7 @@ public class SampleImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { @Inject ImageDataStoreHelper imageStoreHelper; @Inject - ImageDataStoreManager imageStoreMgr; + ImageDataStoreProviderManager imageStoreMgr; public SampleImageDataStoreLifeCycle() { } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java index c6a8e0aa0ae..2ad9602a7bb 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java @@ -31,7 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider import org.apache.cloudstack.storage.datastore.driver.SampleImageDataStoreDriverImpl; import org.apache.cloudstack.storage.datastore.lifecycle.SampleImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreManager; +import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; import com.cloud.utils.component.ComponentContext; @@ -41,7 +41,7 @@ public class SampleImageDataStoreProvider implements ImageDataStoreProvider { protected ImageDataStoreLifeCycle lifeCycle; protected ImageDataStoreDriver driver; @Inject - ImageDataStoreManager storeMgr; + ImageDataStoreProviderManager storeMgr; long id; String uuid; @Override From ae14d4bab42ba3290ab8a9fab21150e155605ac2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 1 Apr 2013 14:16:34 -0700 Subject: [PATCH 004/303] add image_data_store_details to store more properties for s3, swift like data store properties. --- setup/db/db/schema-410to420.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index a3a756ed085..c48cb5e72af 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -79,6 +79,16 @@ CREATE TABLE `cloud`.`image_data_store` ( PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`image_data_store_details` ( + `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', + `store_id` bigint unsigned NOT NULL COMMENT 'store the detail is related to', + `name` varchar(255) NOT NULL COMMENT 'name of the detail', + `value` varchar(255) NOT NULL COMMENT 'value of the detail', + PRIMARY KEY (`id`), + CONSTRAINT `fk_image_data_store_details__store_id` FOREIGN KEY `fk_image_data_store__store_id`(`store_id`) REFERENCES `image_data_store`(`id`) ON DELETE CASCADE, + INDEX `i_image_data_store__name__value`(`name`(128), `value`(128)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + CREATE TABLE `cloud`.`template_store_ref` ( `id` bigint unsigned NOT NULL auto_increment, From 86a384041211457861d25081c01e4bc9f3a125e9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 2 Apr 2013 11:19:49 -0700 Subject: [PATCH 005/303] Fix AddSecondaryStorageCmd to use CloudStack default secondary storage store plugin. --- .../com/cloud/resource/ResourceService.java | 6 +- api/src/com/cloud/storage/ObjectStore.java | 51 ++++++ .../src/com/cloud}/storage/ScopeType.java | 2 +- .../cloudstack/api/ResponseGenerator.java | 4 +- .../admin/host/AddSecondaryStorageCmd.java | 56 +++++-- .../response/ObjectStoreDetailResponse.java | 48 ++++++ .../api/response/ObjectStoreResponse.java | 156 ++++++++++++++++++ .../subsystem/api/storage/ClusterScope.java | 2 + .../api/storage/DataStoreProviderManager.java | 1 + .../subsystem/api/storage/HostScope.java | 2 + .../engine/subsystem/api/storage/Scope.java | 2 + .../subsystem/api/storage/ZoneScope.java | 2 + .../datastore/db/PrimaryDataStoreDao.java | 2 +- .../datastore/db/PrimaryDataStoreDaoImpl.java | 2 +- .../storage/datastore/db/StoragePoolVO.java | 2 +- .../image/store/ImageDataStoreImpl.java | 35 +++- .../allocator/StorageAllocatorTest.java | 2 +- .../storage/test/volumeServiceTest.java | 2 +- .../DataStoreProviderManagerImpl.java | 6 + .../endpoint/DefaultEndPointSelector.java | 2 +- .../image/datastore/ImageDataStore.java | 4 +- .../image/datastore/ImageDataStoreHelper.java | 7 +- .../storage/image/db/ImageDataStoreVO.java | 63 +++++-- .../datastore/PrimaryDataStoreHelper.java | 2 +- .../datastore/PrimaryDataStoreImpl.java | 2 +- .../allocator/RandomStoragePoolAllocator.java | 2 +- .../CloudStackImageDataStoreLifeCycle.java | 72 +++++++- .../CloudStackImageDataStoreProvider.java | 2 +- ...oudStackPrimaryDataStoreLifeCycleImpl.java | 2 +- .../src/com/cloud/api/ApiResponseHelper.java | 25 ++- .../cloud/resource/ResourceManagerImpl.java | 115 ++++++++++++- .../com/cloud/storage/StorageManagerImpl.java | 1 - .../com/cloud/storage/VolumeManagerImpl.java | 1 - .../storage/listener/StoragePoolMonitor.java | 2 +- .../resource/MockResourceManagerImpl.java | 9 + setup/db/db/schema-410to420.sql | 2 + 36 files changed, 634 insertions(+), 62 deletions(-) create mode 100644 api/src/com/cloud/storage/ObjectStore.java rename {engine/api/src/org/apache/cloudstack/engine/subsystem/api => api/src/com/cloud}/storage/ScopeType.java (93%) create mode 100644 api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java create mode 100644 api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java index 08e2585d1a7..dbed36e3a82 100755 --- a/api/src/com/cloud/resource/ResourceService.java +++ b/api/src/com/cloud/resource/ResourceService.java @@ -38,6 +38,7 @@ import com.cloud.exception.ResourceInUseException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster; +import com.cloud.storage.ObjectStore; import com.cloud.storage.S3; import com.cloud.storage.Swift; import com.cloud.utils.Pair; @@ -100,7 +101,10 @@ public interface ResourceService { Swift discoverSwift(AddSwiftCmd addSwiftCmd) throws DiscoveryException; S3 discoverS3(AddS3Cmd cmd) throws DiscoveryException; - + + ObjectStore discoverObjectStore(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; + + List getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId); Pair, Integer> listSwifts(ListSwiftsCmd cmd); diff --git a/api/src/com/cloud/storage/ObjectStore.java b/api/src/com/cloud/storage/ObjectStore.java new file mode 100644 index 00000000000..636537f8437 --- /dev/null +++ b/api/src/com/cloud/storage/ObjectStore.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 com.cloud.storage; + +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +public interface ObjectStore extends Identity, InternalIdentity { + + /** + * @return name of the object store. + */ + String getName(); + + /** + * @return availability zone. + */ + Long getDataCenterId(); + + /** + * @return region id. + * @return + */ + Long getRegionId(); + + /** + * @return object store provider name + */ + String getProviderName(); + + + /** + * + * @return data store protocol + */ + String getProtocol(); +} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java b/api/src/com/cloud/storage/ScopeType.java similarity index 93% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java rename to api/src/com/cloud/storage/ScopeType.java index a3d21ce9bef..c9786d8d353 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ScopeType.java +++ b/api/src/com/cloud/storage/ScopeType.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.engine.subsystem.api.storage; +package com.cloud.storage; public enum ScopeType { HOST, diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index d1e13023117..b85f2c5f7ed 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -326,6 +326,8 @@ public interface ResponseGenerator { RegionResponse createRegionResponse(Region region); + ObjectStoreResponse createObjectStoreResponse(ObjectStore os); + /** * @param resourceTag * @param keyValueOnly TODO @@ -384,7 +386,7 @@ public interface ResponseGenerator { GuestOSResponse createGuestOSResponse(GuestOS os); SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched); - + UsageRecordResponse createUsageResponse(Usage usageRecord); TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor); diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java index f1d12b3b07b..663750edcc8 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.api.command.admin.host; import java.util.List; +import java.util.Map; import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; @@ -24,12 +25,16 @@ 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.HostResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.cloudstack.api.response.RegionResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.log4j.Logger; import com.cloud.exception.DiscoveryException; import com.cloud.host.Host; +import com.cloud.storage.ObjectStore; import com.cloud.user.Account; @APICommand(name = "addSecondaryStorage", description="Adds secondary storage.", responseObject=HostResponse.class) @@ -48,6 +53,21 @@ public class AddSecondaryStorageCmd extends BaseCmd { description="the Zone ID for the secondary storage") private Long zoneId; + @Parameter(name=ApiConstants.REGION_ID, type=CommandType.UUID, entityType=RegionResponse.class, + description="the Region ID for the secondary storage") + private Long regionId; + + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the secondary storage data store") + private Map details; + + @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, + required=false, description="the scope of the secondary storage data store: zone or region or global") + private String scope; + + @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, + required=false, description="the secondary storage store provider name") + private String imageProviderName; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -60,6 +80,23 @@ public class AddSecondaryStorageCmd extends BaseCmd { return zoneId; } + public Long getRegionId() { + return regionId; + } + + public Map getDetails() { + return details; + } + + public String getScope() { + return this.scope; + } + + public String getImageProviderName() { + return this.imageProviderName; + } + + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// @@ -76,17 +113,14 @@ public class AddSecondaryStorageCmd extends BaseCmd { @Override public void execute(){ - try { - List result = _resourceService.discoverHosts(this); - HostResponse hostResponse = null; - if (result != null && result.size() > 0) { - for (Host host : result) { - // There should only be one secondary storage host per add - hostResponse = _responseGenerator.createHostResponse(host); - hostResponse.setResponseName(getCommandName()); - hostResponse.setObjectName("secondarystorage"); - this.setResponseObject(hostResponse); - } + try{ + ObjectStore result = _resourceService.discoverObjectStore(this); + ObjectStoreResponse storeResponse = null; + if (result != null ) { + storeResponse = _responseGenerator.createObjectStoreResponse(result); + storeResponse.setResponseName(getCommandName()); + storeResponse.setObjectName("secondarystorage"); + this.setResponseObject(storeResponse); } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage"); } diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java b/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java new file mode 100644 index 00000000000..b532c2848a7 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java @@ -0,0 +1,48 @@ +// 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.response; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class ObjectStoreDetailResponse extends BaseResponse { + @SerializedName("name") @Param(description="detail property name of the object store") + private String name; + + @SerializedName("value") @Param(description="detail property value of the object store") + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + +} diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java b/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java new file mode 100644 index 00000000000..de3a26f27d6 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java @@ -0,0 +1,156 @@ +// 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.response; + +import java.util.Date; + +import javax.persistence.Column; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.EntityReference; + +import com.cloud.serializer.Param; +import com.cloud.storage.ObjectStore; +import com.cloud.storage.ScopeType; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolStatus; +import com.google.gson.annotations.SerializedName; + +@EntityReference(value=ObjectStore.class) +public class ObjectStoreResponse extends BaseResponse { + @SerializedName("id") @Param(description="the ID of the object store") + private String id; + + @SerializedName("zoneid") @Param(description="the Zone ID of the object store") + private String zoneId; + + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the object store") + private String zoneName; + + @SerializedName("regionid") @Param(description="the Region ID of the object store") + private String regionId; + + @SerializedName("regionname") @Param(description="the Region name of the object store") + private String regionName; + + @SerializedName("name") @Param(description="the name of the object store") + private String name; + + @SerializedName("url") @Param(description="the url of the object store") + private String url; + + @SerializedName("providername") @Param(description="the provider name of the object store") + private String providerName; + + @SerializedName("scope") @Param(description="the scope of the object store") + private ScopeType type; + + @SerializedName("details") @Param(description="the details of the object store") + private String details; + + + + @Override + public String getObjectId() { + return this.getId(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getZoneId() { + return zoneId; + } + + public void setZoneId(String zoneId) { + this.zoneId = zoneId; + } + + public String getZoneName() { + return zoneName; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + + public String getRegionId() { + return regionId; + } + + public void setRegionId(String regionId) { + this.regionId = regionId; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public ScopeType getType() { + return type; + } + + public void setType(ScopeType type) { + this.type = type; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + + +} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java index 0f0e9581523..938f055b2d9 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.ScopeType; + public class ClusterScope extends AbstractScope { private ScopeType type = ScopeType.CLUSTER; 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 906720a1f41..8dd8c3a0824 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 @@ -26,6 +26,7 @@ import com.cloud.utils.component.Manager; public interface DataStoreProviderManager extends Manager, DataStoreProviderApiService { public DataStoreProvider getDataStoreProvider(String name); public DataStoreProvider getDefaultPrimaryDataStoreProvider(); + public DataStoreProvider getDefaultImageDataStoreProvider(); public List getDataStoreProviders(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java index c5e90ac894c..57a448ff2db 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.ScopeType; + public class HostScope extends AbstractScope { private ScopeType type = ScopeType.HOST; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java index 91d4734ef15..25226f984ea 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.ScopeType; + public interface Scope { public ScopeType getScopeType(); public boolean isSameScope(Scope scope); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java index 2d3d41f22b5..a71a9c7ffb5 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.ScopeType; + public class ZoneScope extends AbstractScope { private ScopeType type = ScopeType.ZONE; diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java index 4d845252f57..16fed3586aa 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java @@ -20,8 +20,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.GenericDao; /** diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 7fcddf1940f..7e7e6fd4002 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -28,11 +28,11 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.springframework.stereotype.Component; import com.cloud.host.Status; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.DB; diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java index 55b2314f0fd..6a7c8544c53 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java @@ -29,9 +29,9 @@ import javax.persistence.TableGenerator; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.GenericDao; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java index 5761033c351..4a6016c699d 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java @@ -52,9 +52,9 @@ public class ImageDataStoreImpl implements ImageDataStore { boolean needDownloadToCacheStorage = false; public ImageDataStoreImpl() { - + } - + protected void configure(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, ImageDataStoreProvider provider) { this.driver = imageDataStoreDriver; @@ -99,7 +99,7 @@ public class ImageDataStoreImpl implements ImageDataStore { @Override public Scope getScope() { - return new ZoneScope(imageDataStoreVO.getDcId()); + return new ZoneScope(imageDataStoreVO.getDataCenterId()); } @Override @@ -142,4 +142,33 @@ public class ImageDataStoreImpl implements ImageDataStore { // TODO Auto-generated method stub return false; } + + @Override + public String getName() { + return imageDataStoreVO.getName(); + } + + @Override + public Long getDataCenterId() { + return imageDataStoreVO.getDataCenterId(); + } + + @Override + public Long getRegionId() { + return imageDataStoreVO.getRegionId(); + } + + @Override + public String getProviderName() { + return imageDataStoreVO.getProviderName(); + } + + @Override + public String getProtocol() { + return imageDataStoreVO.getProtocol(); + } + + + + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java index c6ebf2e7fb5..b369459a9a8 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java @@ -28,7 +28,6 @@ import junit.framework.Assert; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailVO; @@ -55,6 +54,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.storage.DiskOfferingVO; +import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index b542e85be22..293d7fb11c8 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -40,7 +40,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -74,6 +73,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceState; +import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index c6911df31d3..aa1ace21a76 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -139,6 +139,12 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return this.getDataStoreProvider("cloudstack primary data store provider"); } + + @Override + public DataStoreProvider getDefaultImageDataStoreProvider() { + return this.getDataStoreProvider("cloudstack image data store provider"); + } + @Override public List getDataStoreProviders(String type) { if (type == null) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index c385abe9624..772a8f29aef 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.HypervisorHostEndPoint; import org.apache.log4j.Logger; @@ -40,6 +39,7 @@ import org.springframework.stereotype.Component; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; +import com.cloud.storage.ScopeType; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java index ed2274e3d40..a9b7e9bc5aa 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java @@ -26,7 +26,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -public interface ImageDataStore extends DataStore { +import com.cloud.storage.ObjectStore; + +public interface ImageDataStore extends DataStore, ObjectStore { TemplateInfo getTemplate(long templateId); VolumeInfo getVolume(long volumeId); SnapshotInfo getSnapshot(long snapshotId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java index 3f1632cf13c..e31a644d1c9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java @@ -22,11 +22,11 @@ import java.util.Map; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; import org.springframework.stereotype.Component; +import com.cloud.storage.ScopeType; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -44,16 +44,17 @@ public class ImageDataStoreHelper { store.setProviderName((String)params.get("providerName")); store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); + store.setUrl((String)params.get("url")); store = imageStoreDao.persist(store); return store; } - + public boolean deleteImageDataStore(long id) { ImageDataStoreVO store = imageStoreDao.findById(id); if (store == null) { throw new CloudRuntimeException("can't find image store:" + id); } - + imageStoreDao.remove(id); return true; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java index 4cb402a1271..3e0d8386d9c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java @@ -26,11 +26,13 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; + +import com.cloud.storage.ObjectStore; +import com.cloud.storage.ScopeType; @Entity @Table(name = "image_data_store") -public class ImageDataStoreVO { +public class ImageDataStoreVO implements ObjectStore { @Id @TableGenerator(name = "image_data_store_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "image_data_store_seq", allocationSize = 1) @Column(name = "id", nullable = false) @@ -38,24 +40,30 @@ public class ImageDataStoreVO { @Column(name = "name", nullable = false) private String name; - + @Column(name = "uuid", nullable = false) private String uuid; - + @Column(name = "protocol", nullable = false) private String protocol; + @Column(name = "url", nullable = false) + private String url; + @Column(name = "image_provider_name", nullable = false) private String providerName; - + @Column(name = "data_center_id") private long dcId; - + + @Column(name = "region_id") + private long regionId; + @Column(name = "scope") @Enumerated(value = EnumType.STRING) private ScopeType scope; - - + + public long getId() { return this.id; } @@ -75,36 +83,55 @@ public class ImageDataStoreVO { public void setProviderName(String provider) { this.providerName = provider; } - + public void setProtocol(String protocol) { this.protocol = protocol; } - + public String getProtocol() { return this.protocol; } - - public void setDcId(long dcId) { + + public void setDataCenterId(long dcId) { this.dcId = dcId; } - - public long getDcId() { + + public Long getDataCenterId() { return this.dcId; } - + + + public Long getRegionId() { + return regionId; + } + + public void setRegionId(long regionId) { + this.regionId = regionId; + } + public ScopeType getScope() { return this.scope; } - + public void setScope(ScopeType scope) { this.scope = scope; } - + public void setUuid(String uuid) { this.uuid = uuid; } - + public String getUuid() { return this.uuid; } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java index 5f8daf42bb3..c5f7a1b2352 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java @@ -28,7 +28,6 @@ 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.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -42,6 +41,7 @@ import com.cloud.alert.AlertManager; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; +import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index b695ff09c2e..3266eaf5631 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -35,7 +35,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; @@ -49,6 +48,7 @@ import org.apache.log4j.Logger; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateStoragePoolVO; diff --git a/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java b/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java index cbe6647ded8..5de3f6be796 100644 --- a/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java +++ b/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java @@ -21,13 +21,13 @@ import java.util.List; import javax.ejb.Local; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import com.cloud.deploy.DeploymentPlan; import com.cloud.deploy.DeploymentPlanner.ExcludeList; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePool; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java index dce40d97dbc..f111dfaf8df 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java @@ -16,6 +16,11 @@ // under the License. package org.apache.cloudstack.storage.datastore.lifecycle; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.inject.Inject; @@ -29,23 +34,88 @@ import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManag import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; +import org.apache.log4j.Logger; import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.exception.DiscoveryException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase; +import com.cloud.resource.Discoverer; +import com.cloud.resource.ResourceListener; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ServerResource; +import com.cloud.storage.ScopeType; +import com.cloud.utils.UriUtils; public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { + + private static final Logger s_logger = Logger + .getLogger(CloudStackImageDataStoreLifeCycle.class); + @Inject + protected ResourceManager _resourceMgr; @Inject protected ImageDataStoreDao imageStoreDao; @Inject ImageDataStoreHelper imageStoreHelper; @Inject ImageDataStoreProviderManager imageStoreMgr; + + protected List _discoverers; + public List getDiscoverers() { + return _discoverers; + } + public void setDiscoverers(List _discoverers) { + this._discoverers = _discoverers; + } + public CloudStackImageDataStoreLifeCycle() { } @Override public DataStore initialize(Map dsInfos) { - ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(dsInfos); + + Long dcId = (Long) dsInfos.get("zoneId"); + String url = (String) dsInfos.get("url"); + String providerName = (String)dsInfos.get("providerName"); + + s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); + + URI uri = null; + try { + uri = new URI(UriUtils.encodeURIComponent(url)); + if (uri.getScheme() == null) { + throw new InvalidParameterValueException("uri.scheme is null " + + url + ", add nfs:// as a prefix"); + } else if (uri.getScheme().equalsIgnoreCase("nfs")) { + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") + || uri.getPath() == null + || uri.getPath().equalsIgnoreCase("")) { + throw new InvalidParameterValueException( + "Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); + } + } + } catch (URISyntaxException e) { + throw new InvalidParameterValueException(url + + " is not a valid uri"); + } + + if ( dcId == null ){ + throw new InvalidParameterValueException("DataCenter id is null, and cloudstack default image storehas to be associated with a data center"); + } + + + Map imageStoreParameters = new HashMap(); + imageStoreParameters.put("name", url); + imageStoreParameters.put("zoneId", dcId); + imageStoreParameters.put("url", url); + imageStoreParameters.put("protocol", uri.getScheme().toLowerCase()); + imageStoreParameters.put("scope", ScopeType.ZONE); + imageStoreParameters.put("providerName", providerName); + + ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(imageStoreParameters); return imageStoreMgr.getImageDataStore(ids.getId()); } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java index c91aa1e3af2..1e88da3f583 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java @@ -30,7 +30,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.storage.datastore.driver.CloudStackImageDataStoreDriverImpl; import org.apache.cloudstack.storage.datastore.lifecycle.CloudStackImageDataStoreLifeCycle; import org.apache.cloudstack.storage.image.ImageDataStoreDriver; @@ -39,6 +38,7 @@ import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManag import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; import org.springframework.stereotype.Component; +import com.cloud.storage.ScopeType; import com.cloud.utils.component.ComponentContext; @Component diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index 51ea2126756..4308558bf0c 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -35,7 +35,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -62,6 +61,7 @@ import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; import com.cloud.storage.OCFS2Manager; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolAutomation; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 64be7f8758a..90543316cf5 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -80,6 +80,7 @@ import org.apache.cloudstack.api.response.NetworkOfferingResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.cloudstack.api.response.NicResponse; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; import org.apache.cloudstack.api.response.PhysicalNetworkResponse; import org.apache.cloudstack.api.response.PodResponse; import org.apache.cloudstack.api.response.PrivateGatewayResponse; @@ -235,6 +236,7 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.ObjectStore; import com.cloud.storage.S3; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; @@ -439,7 +441,7 @@ public class ApiResponseHelper implements ResponseGenerator { vmSnapshotResponse.setCreated(vmSnapshot.getCreated()); vmSnapshotResponse.setDescription(vmSnapshot.getDescription()); vmSnapshotResponse.setDisplayName(vmSnapshot.getDisplayName()); - UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId()); + UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId()); if(vm!=null) vmSnapshotResponse.setVirtualMachineid(vm.getUuid()); if(vmSnapshot.getParent() != null) @@ -449,7 +451,7 @@ public class ApiResponseHelper implements ResponseGenerator { vmSnapshotResponse.setObjectName("vmsnapshot"); return vmSnapshotResponse; } - + @Override public SnapshotPolicyResponse createSnapshotPolicyResponse(SnapshotPolicy policy) { SnapshotPolicyResponse policyResponse = new SnapshotPolicyResponse(); @@ -546,7 +548,7 @@ public class ApiResponseHelper implements ResponseGenerator { vlanResponse.setIp6Gateway(vlan.getIp6Gateway()); vlanResponse.setIp6Cidr(vlan.getIp6Cidr()); - + String ip6Range = vlan.getIp6Range(); if (ip6Range != null) { String[] range = ip6Range.split("-"); @@ -887,6 +889,15 @@ public class ApiResponseHelper implements ResponseGenerator { } + + @Override + public ObjectStoreResponse createObjectStoreResponse(ObjectStore os) { + // TODO Auto-generated method stub + return null; + } + + + @Override public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) { ClusterResponse clusterResponse = new ClusterResponse(); @@ -2249,7 +2260,7 @@ public class ApiResponseHelper implements ResponseGenerator { if (((network.getCidr()) != null) && (network.getNetworkCidr() == null)) { response.setNetmask(NetUtils.cidr2Netmask(network.getCidr())); } - + response.setIp6Gateway(network.getIp6Gateway()); response.setIp6Cidr(network.getIp6Cidr()); @@ -2444,7 +2455,7 @@ public class ApiResponseHelper implements ResponseGenerator { List cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId()); response.setCidrList(StringUtils.join(cidrs, ",")); - + if (fwRule.getTrafficType() == FirewallRule.TrafficType.Ingress) { IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId()); response.setPublicIpAddressId(ip.getId()); @@ -3475,7 +3486,7 @@ public class ApiResponseHelper implements ResponseGenerator { return usageRecResponse; } - + public String getDateStringInternal(Date inputDate) { if (inputDate == null) return null; @@ -3559,7 +3570,7 @@ public class ApiResponseHelper implements ResponseGenerator { return sb.toString(); } - + @Override public TrafficMonitorResponse createTrafficMonitorResponse(Host trafficMonitor) { Map tmDetails = ApiDBUtils.findHostDetailsById(trafficMonitor.getId()); diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 82bca5194bf..e9b0c827ab7 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -45,6 +45,17 @@ import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd; +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; +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.PrimaryDataStoreInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.region.RegionVO; +import org.apache.cloudstack.region.dao.RegionDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -107,8 +118,10 @@ import com.cloud.org.Grouping.AllocationState; import com.cloud.org.Managed; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.ObjectStore; import com.cloud.storage.S3; import com.cloud.storage.S3VO; +import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; @@ -167,7 +180,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, StorageManager _storageMgr; @Inject protected SecondaryStorageVmManager _secondaryStorageMgr; - + @Inject + DataStoreProviderManager _dataStoreProviderMgr; + @Inject + protected RegionDao _regionDao; @Inject protected DataCenterDao _dcDao; @Inject @@ -206,6 +222,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, protected HighAvailabilityManager _haMgr; @Inject protected StorageService _storageSvr; + @Inject + DataStoreManager _dataStoreMgr; + protected List _discoverers; public List getDiscoverers() { @@ -639,6 +658,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), true); } + + + + @Override public List discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, @@ -669,6 +692,96 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return this._s3Mgr.listS3s(cmd); } + @Override + public ObjectStore discoverObjectStore(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, + InvalidParameterValueException { + String providerName = cmd.getImageProviderName(); + DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); + + if (storeProvider == null) { + storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider(); + if (storeProvider == null) { + throw new InvalidParameterValueException( + "can't find image store provider: " + providerName); + } + } + + Long dcId = cmd.getZoneId(); + Long regionId = cmd.getRegionId(); + String url = cmd.getUrl(); + Map details = cmd.getDetails(); + + ScopeType scopeType = ScopeType.ZONE; + String scope = cmd.getScope(); + if (scope != null) { + try { + scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); + } catch (Exception e) { + throw new InvalidParameterValueException("invalid scope" + + scope); + } + } + if (scopeType == ScopeType.ZONE && dcId == null) { + throw new InvalidParameterValueException( + "zone id can't be null, if scope is zone"); + } else if (scopeType == ScopeType.REGION && regionId == null) { + throw new InvalidParameterValueException( + "region id can't be null, if scope is region"); + } + + if ( dcId != null ){ + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(dcId); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + + dcId); + } + + Account account = UserContext.current().getCaller(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() + && !_accountMgr.isRootAdmin(account.getType())) { + PermissionDeniedException ex = new PermissionDeniedException( + "Cannot perform this operation, Zone with specified id is currently disabled"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; + } + } + + if ( regionId != null ){ + // Check if the region exists in the system + RegionVO region = _regionDao.findById(regionId.intValue()); + if (region == null) { + throw new InvalidParameterValueException("Can't find region by id " + + regionId); + } + } + + Map params = new HashMap(); + params.put("zoneId", dcId); + params.put("regionId", regionId); + params.put("url", cmd.getUrl()); + params.put("name", cmd.getUrl()); + params.put("details", details); + params.put("providerName", storeProvider.getName()); + + DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); + DataStore store = null; + try { + store = lifeCycle.initialize(params); + + if (scopeType == ScopeType.ZONE) { + ZoneScope zoneScope = new ZoneScope(dcId); + lifeCycle.attachZone(store, zoneScope); + } + } catch (Exception e) { + s_logger.debug("Failed to add data store", e); + throw new CloudRuntimeException("Failed to add data store", e); + } + + return (ObjectStore)_dataStoreMgr.getDataStore(store.getId(), + DataStoreRole.Image); + } + private List discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List hostTags, Map params, boolean deferAgentCreation) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { URI uri = null; diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 4e410e4b41e..72a0e0741f2 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -55,7 +55,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 1e8edafe4e2..ddd6ff00b83 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -49,7 +49,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java index f957ca31ada..e035fd7c26f 100755 --- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java +++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java @@ -20,7 +20,6 @@ import java.util.List; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -38,6 +37,7 @@ import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.OCFS2Manager; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManagerImpl; import com.cloud.storage.StoragePoolStatus; diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/test/com/cloud/resource/MockResourceManagerImpl.java index 5202c317e56..df62d2e6bc9 100644 --- a/server/test/com/cloud/resource/MockResourceManagerImpl.java +++ b/server/test/com/cloud/resource/MockResourceManagerImpl.java @@ -49,6 +49,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster; import com.cloud.resource.ResourceState.Event; import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.ObjectStore; import com.cloud.storage.S3; import com.cloud.storage.Swift; import com.cloud.template.VirtualMachineTemplate; @@ -608,4 +609,12 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana return null; } + @Override + public ObjectStore discoverObjectStore(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, + InvalidParameterValueException { + // TODO Auto-generated method stub + return null; + } + + } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index c48cb5e72af..da5d5d5dcdb 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -73,7 +73,9 @@ CREATE TABLE `cloud`.`image_data_store` ( `name` varchar(255) NOT NULL COMMENT 'name of data store', `image_provider_name` varchar(255) NOT NULL COMMENT 'id of image_data_store_provider', `protocol` varchar(255) NOT NULL COMMENT 'protocol of data store', + `url` varchar(255) COMMENT 'url for image data store', `data_center_id` bigint unsigned COMMENT 'datacenter id of data store', + `region_id` bigint unsigned COMMENT 'region id of data store', `scope` varchar(255) COMMENT 'scope of data store', `uuid` varchar(255) COMMENT 'uuid of data store', PRIMARY KEY(`id`) From 7699485b4fb6a98d94a4fec194c54cf87db43880 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 2 Apr 2013 18:15:15 -0700 Subject: [PATCH 006/303] Create DB view for Image Data Store. --- .../response/ObjectStoreDetailResponse.java | 38 ++++ .../api/response/ObjectStoreResponse.java | 48 +++-- .../datastore/db/ImageDataStoreDetailVO.java | 81 +++++++ .../db/ImageDataStoreDetailsDao.java | 28 +++ server/src/com/cloud/api/ApiDBUtils.java | 22 +- .../src/com/cloud/api/ApiResponseHelper.java | 9 +- .../cloud/api/query/ViewResponseHelper.java | 20 ++ .../api/query/dao/ImageDataStoreJoinDao.java | 36 ++++ .../query/dao/ImageDataStoreJoinDaoImpl.java | 164 ++++++++++++++ .../api/query/vo/ImageDataStoreJoinVO.java | 201 ++++++++++++++++++ .../storage/dao/ImageDataStoreDaoImpl.java | 75 +++++++ setup/db/db/schema-410to420.sql | 28 ++- 12 files changed, 729 insertions(+), 21 deletions(-) create mode 100644 engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java create mode 100644 engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java create mode 100644 server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java create mode 100644 server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java create mode 100644 server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java create mode 100644 server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java b/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java index b532c2848a7..74a42f2612a 100644 --- a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java @@ -28,6 +28,16 @@ public class ObjectStoreDetailResponse extends BaseResponse { @SerializedName("value") @Param(description="detail property value of the object store") private String value; + public ObjectStoreDetailResponse(){ + super(); + } + + public ObjectStoreDetailResponse(String name, String val){ + super(); + this.name = name; + this.value = val; + } + public String getName() { return name; } @@ -44,5 +54,33 @@ public class ObjectStoreDetailResponse extends BaseResponse { this.value = value; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + String oid = this.getName(); + result = prime * result + ((oid== null) ? 0 : oid.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ObjectStoreDetailResponse other = (ObjectStoreDetailResponse) obj; + String oid = this.getName(); + if (oid == null) { + if (other.getName() != null) + return false; + } else if (!oid.equals(other.getName())) + return false; + else if ( this.getValue().equals(other.getValue())) + return false; + return true; + } } diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java b/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java index de3a26f27d6..595ae9732e0 100644 --- a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java @@ -16,9 +16,8 @@ // under the License. package org.apache.cloudstack.api.response; -import java.util.Date; - -import javax.persistence.Column; +import java.util.LinkedHashSet; +import java.util.Set; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -27,8 +26,6 @@ import org.apache.cloudstack.api.EntityReference; import com.cloud.serializer.Param; import com.cloud.storage.ObjectStore; import com.cloud.storage.ScopeType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; import com.google.gson.annotations.SerializedName; @EntityReference(value=ObjectStore.class) @@ -43,7 +40,7 @@ public class ObjectStoreResponse extends BaseResponse { private String zoneName; @SerializedName("regionid") @Param(description="the Region ID of the object store") - private String regionId; + private Long regionId; @SerializedName("regionname") @Param(description="the Region name of the object store") private String regionName; @@ -54,16 +51,22 @@ public class ObjectStoreResponse extends BaseResponse { @SerializedName("url") @Param(description="the url of the object store") private String url; + @SerializedName("protocol") @Param(description="the protocol of the object store") + private String protocol; + @SerializedName("providername") @Param(description="the provider name of the object store") private String providerName; @SerializedName("scope") @Param(description="the scope of the object store") - private ScopeType type; + private ScopeType scope; @SerializedName("details") @Param(description="the details of the object store") - private String details; + private Set details; + public ObjectStoreResponse(){ + this.details = new LinkedHashSet(); + } @Override public String getObjectId() { @@ -95,11 +98,11 @@ public class ObjectStoreResponse extends BaseResponse { } - public String getRegionId() { + public Long getRegionId() { return regionId; } - public void setRegionId(String regionId) { + public void setRegionId(Long regionId) { this.regionId = regionId; } @@ -135,22 +138,35 @@ public class ObjectStoreResponse extends BaseResponse { this.providerName = providerName; } - public ScopeType getType() { - return type; + public ScopeType getScope() { + return scope; } - public void setType(ScopeType type) { - this.type = type; + public void setScope(ScopeType type) { + this.scope = type; } - public String getDetails() { + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public Set getDetails() { return details; } - public void setDetails(String details) { + public void setDetails(Set details) { this.details = details; } + public void addDetail(ObjectStoreDetailResponse detail){ + this.details.add(detail); + } + } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java new file mode 100644 index 00000000000..c980cf15693 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java @@ -0,0 +1,81 @@ +// 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.datastore.db; + +import org.apache.cloudstack.api.InternalIdentity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name="image_data_store_details") +public class ImageDataStoreDetailVO implements InternalIdentity { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="store_id") + long storeId; + + @Column(name="name") + String name; + + @Column(name="value") + String value; + + public ImageDataStoreDetailVO(long storeId, String name, String value) { + this.storeId = storeId; + this.name = name; + this.value = value; + } + + public long getId() { + return id; + } + + public long getStoreId() { + return storeId; + } + + public void setStoreId(long storeId) { + this.storeId = storeId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + protected ImageDataStoreDetailVO() { + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java new file mode 100644 index 00000000000..781efcfb95e --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.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.storage.datastore.db; + +import java.util.Map; + + +import com.cloud.utils.db.GenericDao; + +public interface ImageDataStoreDetailsDao extends GenericDao { + + void update(long storeId, Map details); + Map getDetails(long storeId); +} diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 7b441901d5e..41f0759152f 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -34,6 +34,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; import org.apache.cloudstack.api.response.ProjectResponse; @@ -55,6 +56,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; import com.cloud.api.query.dao.DomainRouterJoinDao; import com.cloud.api.query.dao.HostJoinDao; +import com.cloud.api.query.dao.ImageDataStoreJoinDao; import com.cloud.api.query.dao.InstanceGroupJoinDao; import com.cloud.api.query.dao.ProjectAccountJoinDao; import com.cloud.api.query.dao.ProjectInvitationJoinDao; @@ -73,6 +75,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -284,7 +287,7 @@ public class ApiDBUtils { static NetworkModel _networkModel; static NetworkManager _networkMgr; static TemplateManager _templateMgr; - + static StatsCollector _statsCollector; static AccountDao _accountDao; @@ -362,6 +365,7 @@ public class ApiDBUtils { static HostJoinDao _hostJoinDao; static VolumeJoinDao _volJoinDao; static StoragePoolJoinDao _poolJoinDao; + static ImageDataStoreJoinDao _imageStoreJoinDao; static AccountJoinDao _accountJoinDao; static AsyncJobJoinDao _jobJoinDao; @@ -466,6 +470,7 @@ public class ApiDBUtils { @Inject private HostJoinDao hostJoinDao; @Inject private VolumeJoinDao volJoinDao; @Inject private StoragePoolJoinDao poolJoinDao; + @Inject private ImageDataStoreJoinDao imageStoreJoinDao; @Inject private AccountJoinDao accountJoinDao; @Inject private AsyncJobJoinDao jobJoinDao; @@ -566,6 +571,7 @@ public class ApiDBUtils { _hostJoinDao = hostJoinDao; _volJoinDao = volJoinDao; _poolJoinDao = poolJoinDao; + _imageStoreJoinDao = imageStoreJoinDao; _accountJoinDao = accountJoinDao; _jobJoinDao = jobJoinDao; @@ -1535,6 +1541,18 @@ public class ApiDBUtils { return _poolJoinDao.newStoragePoolView(vr); } + public static ObjectStoreResponse newImageStoreResponse(ImageDataStoreJoinVO vr) { + return _imageStoreJoinDao.newObjectStoreResponse(vr); + } + + public static ObjectStoreResponse fillImageStoreDetails(ObjectStoreResponse vrData, ImageDataStoreJoinVO vr){ + return _imageStoreJoinDao.setObjectStoreResponse(vrData, vr); + } + + public static List newImageStoreView(ObjectStore vr){ + return _imageStoreJoinDao.newObjectStoreView(vr); + } + public static AccountResponse newAccountResponse(AccountJoinVO ve) { return _accountJoinDao.newAccountResponse(ve); @@ -1579,7 +1597,7 @@ public class ApiDBUtils { public static DataCenterJoinVO newDataCenterView(DataCenter dc){ return _dcJoinDao.newDataCenterView(dc); } - + public static Map findHostDetailsById(long hostId){ return _hostDetailsDao.findDetails(hostId); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 90543316cf5..03ed97da640 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -142,6 +142,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -892,8 +893,12 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public ObjectStoreResponse createObjectStoreResponse(ObjectStore os) { - // TODO Auto-generated method stub - return null; + List viewStores = ApiDBUtils.newImageStoreView(os); + List listStores = ViewResponseHelper.createObjectStoreResponse(viewStores.toArray(new ImageDataStoreJoinVO[viewStores.size()])); + assert listStores != null && listStores.size() == 1 : "There should be one image data store returned"; + return listStores.get(0); + + } diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 9e612b07d1b..a1d1bf824a1 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; import org.apache.cloudstack.api.response.ProjectResponse; @@ -51,6 +52,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -263,6 +265,24 @@ public class ViewResponseHelper { return new ArrayList(vrDataList.values()); } + public static List createObjectStoreResponse(ImageDataStoreJoinVO... stores) { + Hashtable vrDataList = new Hashtable(); + // Initialise the vrdatalist with the input data + for (ImageDataStoreJoinVO vr : stores) { + ObjectStoreResponse vrData = vrDataList.get(vr.getId()); + if ( vrData == null ){ + // first time encountering this vm + vrData = ApiDBUtils.newImageStoreResponse(vr); + } + else{ + // update tags + vrData = ApiDBUtils.fillImageStoreDetails(vrData, vr); + } + vrDataList.put(vr.getId(), vrData); + } + return new ArrayList(vrDataList.values()); + } + public static List createAccountResponse(AccountJoinVO... accounts) { List respList = new ArrayList(); diff --git a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java new file mode 100644 index 00000000000..b92fbe60f4b --- /dev/null +++ b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java @@ -0,0 +1,36 @@ +// 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.api.query.dao; + +import java.util.List; + +import org.apache.cloudstack.api.response.ObjectStoreResponse; +import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.storage.ObjectStore; +import com.cloud.utils.db.GenericDao; + +public interface ImageDataStoreJoinDao extends GenericDao { + + ObjectStoreResponse newObjectStoreResponse(ImageDataStoreJoinVO os); + + ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse response, ImageDataStoreJoinVO os); + + List newObjectStoreView(ObjectStore os); + + List searchByIds(Long... spIds); + +} diff --git a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java new file mode 100644 index 00000000000..c58f954e03a --- /dev/null +++ b/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java @@ -0,0 +1,164 @@ +// 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.api.query.dao; + +import java.util.ArrayList; +import java.util.List; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.response.ObjectStoreDetailResponse; +import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.storage.ObjectStore; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + + +@Component +@Local(value={ImageDataStoreJoinDao.class}) +public class ImageDataStoreJoinDaoImpl extends GenericDaoBase implements ImageDataStoreJoinDao { + public static final Logger s_logger = Logger.getLogger(ImageDataStoreJoinDaoImpl.class); + + @Inject + private ConfigurationDao _configDao; + + private final SearchBuilder dsSearch; + + private final SearchBuilder dsIdSearch; + + + protected ImageDataStoreJoinDaoImpl() { + + dsSearch = createSearchBuilder(); + dsSearch.and("idIN", dsSearch.entity().getId(), SearchCriteria.Op.IN); + dsSearch.done(); + + dsIdSearch = createSearchBuilder(); + dsIdSearch.and("id", dsIdSearch.entity().getId(), SearchCriteria.Op.EQ); + dsIdSearch.done(); + + this._count = "select count(distinct id) from image_data_store_view WHERE "; + } + + + + + + @Override + public ObjectStoreResponse newObjectStoreResponse(ImageDataStoreJoinVO ids) { + ObjectStoreResponse osResponse = new ObjectStoreResponse(); + osResponse.setId(ids.getUuid()); + osResponse.setName(ids.getName()); + osResponse.setProviderName(ids.getProviderName()); + osResponse.setProtocol(ids.getProtocol()); + osResponse.setUrl(ids.getUrl()); + osResponse.setScope(ids.getScope()); + osResponse.setZoneId(ids.getZoneUuid()); + osResponse.setZoneName(ids.getZoneName()); + osResponse.setRegionId(ids.getRegionId()); + osResponse.setRegionName(ids.getRegionName()); + + String detailName = ids.getDetailName(); + if ( detailName != null && detailName.length() > 0 ){ + ObjectStoreDetailResponse osdResponse = new ObjectStoreDetailResponse(detailName, ids.getDetailValue()); + osResponse.addDetail(osdResponse); + } + osResponse.setObjectName("objectstore"); + return osResponse; + } + + + + + + @Override + public ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse response, ImageDataStoreJoinVO ids) { + String detailName = ids.getDetailName(); + if ( detailName != null && detailName.length() > 0 ){ + ObjectStoreDetailResponse osdResponse = new ObjectStoreDetailResponse(detailName, ids.getDetailValue()); + response.addDetail(osdResponse); + } + return response; + } + + + + @Override + public List newObjectStoreView(ObjectStore os) { + SearchCriteria sc = dsIdSearch.create(); + sc.setParameters("id", os.getId()); + return searchIncludingRemoved(sc, null, null, false); + + } + + + + @Override + public List searchByIds(Long... spIds) { + // set detail batch query size + int DETAILS_BATCH_SIZE = 2000; + String batchCfg = _configDao.getValue("detail.batch.query.size"); + if ( batchCfg != null ){ + DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg); + } + // query details by batches + List uvList = new ArrayList(); + // query details by batches + int curr_index = 0; + if ( spIds.length > DETAILS_BATCH_SIZE ){ + while ( (curr_index + DETAILS_BATCH_SIZE ) <= spIds.length ) { + Long[] ids = new Long[DETAILS_BATCH_SIZE]; + for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) { + ids[k] = spIds[j]; + } + SearchCriteria sc = dsSearch.create(); + sc.setParameters("idIN", ids); + List vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + curr_index += DETAILS_BATCH_SIZE; + } + } + if (curr_index < spIds.length) { + int batch_size = (spIds.length - curr_index); + // set the ids value + Long[] ids = new Long[batch_size]; + for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) { + ids[k] = spIds[j]; + } + SearchCriteria sc = dsSearch.create(); + sc.setParameters("idIN", ids); + List vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + } + return uvList; + } + + + + +} diff --git a/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java b/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java new file mode 100644 index 00000000000..5858dffb148 --- /dev/null +++ b/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java @@ -0,0 +1,201 @@ +// 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.api.query.vo; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; +import com.cloud.storage.ScopeType; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +/** + * Image Data Store DB view. + * + */ +@Entity +@Table(name="image_data_store_view") +public class ImageDataStoreJoinVO extends BaseViewVO implements InternalIdentity, Identity { + + @Id + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="name") + private String name; + + @Column(name="url") + private String url; + + @Column(name = "protocol") + private String protocol; + + @Column(name = "provider_name", nullable = false) + private String providerName; + + @Column(name="scope") + @Enumerated(value = EnumType.STRING) + private ScopeType scope; + + @Column(name="data_center_id") + private long zoneId; + + @Column(name="data_center_uuid") + private String zoneUuid; + + @Column(name="data_center_name") + private String zoneName; + + @Column(name="region_id") + private long regionId; + + @Column(name="region_name") + private String regionName; + + @Column(name="detail_name") + private String detailName; + + @Column(name="detail_value") + private String detailValue; + + + @Override + public long getId() { + return id; + } + + @Override + public void setId(long id) { + this.id = id; + } + + @Override + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getName() { + return name; + } + + + + public long getZoneId() { + return zoneId; + } + + public void setZoneId(long zoneId) { + this.zoneId = zoneId; + } + + public String getZoneUuid() { + return zoneUuid; + } + + public void setZoneUuid(String zoneUuid) { + this.zoneUuid = zoneUuid; + } + + public String getZoneName() { + return zoneName; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getProtocol() { + return protocol; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProviderName() { + return providerName; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public ScopeType getScope() { + return scope; + } + + public void setScope(ScopeType scope) { + this.scope = scope; + } + + public long getRegionId() { + return regionId; + } + + public void setRegionId(long regionId) { + this.regionId = regionId; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public void setName(String name) { + this.name = name; + } + + public String getDetailName() { + return detailName; + } + + public void setDetailName(String detailName) { + this.detailName = detailName; + } + + public String getDetailValue() { + return detailValue; + } + + public void setDetailValue(String detailValue) { + this.detailValue = detailValue; + } + + + +} diff --git a/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java b/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java new file mode 100644 index 00000000000..1b3fa46b042 --- /dev/null +++ b/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java @@ -0,0 +1,75 @@ +// 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.storage.dao; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.apache.cloudstack.storage.datastore.db.ImageDataStoreDetailVO; +import org.apache.cloudstack.storage.datastore.db.ImageDataStoreDetailsDao; +import org.springframework.stereotype.Component; + +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; + +@Component +@Local(value=ImageDataStoreDetailsDao.class) +public class ImageDataStoreDaoImpl extends GenericDaoBase implements ImageDataStoreDetailsDao { + + protected final SearchBuilder storeSearch; + + protected ImageDataStoreDaoImpl() { + super(); + storeSearch = createSearchBuilder(); + storeSearch.and("store", storeSearch.entity().getStoreId(), SearchCriteria.Op.EQ); + storeSearch.done(); + } + + @Override + public void update(long storeId, Map details) { + Transaction txn = Transaction.currentTxn(); + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store", storeId); + + txn.start(); + expunge(sc); + for (Map.Entry entry : details.entrySet()) { + ImageDataStoreDetailVO detail = new ImageDataStoreDetailVO(storeId, entry.getKey(), entry.getValue()); + persist(detail); + } + txn.commit(); + } + + @Override + public Map getDetails(long storeId) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store", storeId); + + List details = listBy(sc); + Map detailsMap = new HashMap(); + for (ImageDataStoreDetailVO detail : details) { + detailsMap.put(detail.getName(), detail.getValue()); + } + + return detailsMap; + } +} diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index da5d5d5dcdb..ed954619f49 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -91,7 +91,33 @@ CREATE TABLE `cloud`.`image_data_store_details` ( INDEX `i_image_data_store__name__value`(`name`(128), `value`(128)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - +DROP VIEW IF EXISTS `cloud`.`image_data_store_view`; +CREATE VIEW `cloud`.`image_data_store_view` AS + select + image_data_store.id, + image_data_store.uuid, + image_data_store.name, + image_data_store.provider_name, + image_data_store.protocol, + image_data_store.url, + image_data_store.scope, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + region.id region_id, + region.name region_name, + image_data_store_details.name detail_name, + image_data_store_details.value detail_value + from + `cloud`.`image_data_store` + left join + `cloud`.`data_center` ON image_data_store.data_center_id = data_center.id + left join + `cloud`.`region` ON image_data_store.region_id = region.id + left join + `cloud`.`image_data_store_details` ON image_data_store_details.store_id = image_data_store.id; + + CREATE TABLE `cloud`.`template_store_ref` ( `id` bigint unsigned NOT NULL auto_increment, `store_id` bigint unsigned NOT NULL, From a872d6d3063fb1775221b98a1d7c0eb3f1691084 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 5 Apr 2013 17:33:35 -0700 Subject: [PATCH 007/303] Renamed internal classes to use "imageStorexxx" instead of previous "imageDataStorexxx". Add new addImageStoreCmd to use 3 image store provider plugins. --- .../com/cloud/resource/ResourceService.java | 5 +- .../{ObjectStore.java => ImageStore.java} | 12 +- .../cloudstack/api/ResponseGenerator.java | 2 +- .../admin/host/AddSecondaryStorageCmd.java | 23 +- .../admin/storage/AddImageStoreCmd.java | 120 ++ ...nse.java => ImageStoreDetailResponse.java} | 12 +- ...eResponse.java => ImageStoreResponse.java} | 58 +- client/tomcatconf/applicationContext.xml.in | 3 + client/tomcatconf/commands.properties.in | 3 + .../api/storage/DataStoreLifeCycle.java | 2 +- ...eProvider.java => ImageStoreProvider.java} | 2 +- ...ava => ImageStoreProviderManagerImpl.java} | 44 +- ...DataStoreImpl.java => ImageStoreImpl.java} | 33 +- ...ifeCycle.java => ImageStoreLifeCycle.java} | 2 +- .../storage/test/DirectAgentTest.java | 4 +- .../datastore/DataStoreManagerImpl.java | 8 +- .../DataStoreProviderManagerImpl.java | 14 +- ...StoreDriver.java => ImageStoreDriver.java} | 2 +- .../storage/image/TemplateEntityImpl.java | 8 +- .../image/datastore/ImageDataStoreHelper.java | 61 - ...geDataStore.java => ImageStoreEntity.java} | 4 +- .../image/datastore/ImageStoreHelper.java | 99 ++ ...DataStoreInfo.java => ImageStoreInfo.java} | 4 +- ...er.java => ImageStoreProviderManager.java} | 10 +- .../image/db/ImageDataStoreProviderDao.java | 25 - .../db/ImageDataStoreProviderDaoImpl.java | 40 - .../image/db/ImageDataStoreProviderVO.java | 49 - ...geDataStoreDao.java => ImageStoreDao.java} | 4 +- ...oreDaoImpl.java => ImageStoreDaoImpl.java} | 6 +- .../storage/image/db/ImageStoreDetailVO.java} | 14 +- .../image/db/ImageStoreDetailsDao.java} | 4 +- .../image/db/ImageStoreDetailsDaoImpl.java | 22 +- ...mageDataStoreVO.java => ImageStoreVO.java} | 56 +- ...mageDataStoreTO.java => ImageStoreTO.java} | 6 +- .../cloudstack/storage/to/TemplateTO.java | 8 +- plugins/pom.xml | 1 + ...va => CloudStackImageStoreDriverImpl.java} | 6 +- ...=> CloudStackImageStoreLifeCycleImpl.java} | 29 +- ... => CloudStackImageStoreProviderImpl.java} | 45 +- .../driver/S3ImageStoreDriverImpl.java | 250 +++ .../lifecycle/S3ImageStoreLifeCycleImpl.java | 177 ++ .../provider/S3ImageStoreProviderImpl.java | 90 + ...l.java => SampleImageStoreDriverImpl.java} | 6 +- ...ava => SampleImageStoreLifeCycleImpl.java} | 24 +- ...java => SampleImageStoreProviderImpl.java} | 24 +- plugins/storage/image/swift/pom.xml | 56 + .../driver/SwiftImageStoreDriverImpl.java | 250 +++ .../SwiftImageStoreLifeCycleImpl.java | 161 ++ .../provider/SwiftImageStoreProviderImpl.java | 92 ++ server/src/com/cloud/api/ApiDBUtils.java | 23 +- .../src/com/cloud/api/ApiResponseHelper.java | 12 +- .../cloud/api/query/ViewResponseHelper.java | 14 +- ...oreJoinDao.java => ImageStoreJoinDao.java} | 16 +- ...aoImpl.java => ImageStoreJoinDaoImpl.java} | 51 +- ...StoreJoinVO.java => ImageStoreJoinVO.java} | 30 +- .../cloud/api/query/vo/StoragePoolJoinVO.java | 5 +- .../cloud/resource/ResourceManagerImpl.java | 1469 +++++++---------- .../src/com/cloud/storage/s3/S3Manager.java | 3 + .../com/cloud/storage/s3/S3ManagerImpl.java | 26 +- .../resource/MockResourceManagerImpl.java | 4 +- setup/db/db/schema-410to420.sql | 47 +- 61 files changed, 2234 insertions(+), 1446 deletions(-) rename api/src/com/cloud/storage/{ObjectStore.java => ImageStore.java} (86%) create mode 100644 api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java rename api/src/org/apache/cloudstack/api/response/{ObjectStoreDetailResponse.java => ImageStoreDetailResponse.java} (88%) rename api/src/org/apache/cloudstack/api/response/{ObjectStoreResponse.java => ImageStoreResponse.java} (70%) rename engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/{ImageDataStoreProvider.java => ImageStoreProvider.java} (92%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/manager/{ImageDataStoreProviderManagerImpl.java => ImageStoreProviderManagerImpl.java} (57%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/store/{ImageDataStoreImpl.java => ImageStoreImpl.java} (80%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/{ImageDataStoreLifeCycle.java => ImageStoreLifeCycle.java} (93%) rename engine/storage/src/org/apache/cloudstack/storage/image/{ImageDataStoreDriver.java => ImageStoreDriver.java} (93%) delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java rename engine/storage/src/org/apache/cloudstack/storage/image/datastore/{ImageDataStore.java => ImageStoreEntity.java} (93%) create mode 100644 engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java rename engine/storage/src/org/apache/cloudstack/storage/image/datastore/{ImageDataStoreInfo.java => ImageStoreInfo.java} (91%) rename engine/storage/src/org/apache/cloudstack/storage/image/datastore/{ImageDataStoreProviderManager.java => ImageStoreProviderManager.java} (77%) delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDao.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDaoImpl.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderVO.java rename engine/storage/src/org/apache/cloudstack/storage/image/db/{ImageDataStoreDao.java => ImageStoreDao.java} (87%) rename engine/storage/src/org/apache/cloudstack/storage/image/db/{ImageDaoStoreDaoImpl.java => ImageStoreDaoImpl.java} (80%) rename engine/{api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java => storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java} (87%) rename engine/{api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java => storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java} (87%) rename server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java => engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java (70%) rename engine/storage/src/org/apache/cloudstack/storage/image/db/{ImageDataStoreVO.java => ImageStoreVO.java} (74%) rename engine/storage/src/org/apache/cloudstack/storage/to/{ImageDataStoreTO.java => ImageStoreTO.java} (87%) rename plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/{CloudStackImageDataStoreDriverImpl.java => CloudStackImageStoreDriverImpl.java} (97%) rename plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/{CloudStackImageDataStoreLifeCycle.java => CloudStackImageStoreLifeCycleImpl.java} (84%) rename plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/{CloudStackImageDataStoreProvider.java => CloudStackImageStoreProviderImpl.java} (60%) create mode 100644 plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java create mode 100644 plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java create mode 100644 plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java rename plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/{SampleImageDataStoreDriverImpl.java => SampleImageStoreDriverImpl.java} (96%) rename plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/{SampleImageDataStoreLifeCycle.java => SampleImageStoreLifeCycleImpl.java} (78%) rename plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/{SampleImageDataStoreProvider.java => SampleImageStoreProviderImpl.java} (77%) create mode 100644 plugins/storage/image/swift/pom.xml create mode 100644 plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java create mode 100644 plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java create mode 100644 plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java rename server/src/com/cloud/api/query/dao/{ImageDataStoreJoinDao.java => ImageStoreJoinDao.java} (62%) rename server/src/com/cloud/api/query/dao/{ImageDataStoreJoinDaoImpl.java => ImageStoreJoinDaoImpl.java} (69%) rename server/src/com/cloud/api/query/vo/{ImageDataStoreJoinVO.java => ImageStoreJoinVO.java} (87%) diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java index dbed36e3a82..d8c09d9662c 100755 --- a/api/src/com/cloud/resource/ResourceService.java +++ b/api/src/com/cloud/resource/ResourceService.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd; import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; +import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; @@ -38,7 +39,7 @@ import com.cloud.exception.ResourceInUseException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.Swift; import com.cloud.utils.Pair; @@ -102,7 +103,7 @@ public interface ResourceService { S3 discoverS3(AddS3Cmd cmd) throws DiscoveryException; - ObjectStore discoverObjectStore(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; + ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; List getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId); diff --git a/api/src/com/cloud/storage/ObjectStore.java b/api/src/com/cloud/storage/ImageStore.java similarity index 86% rename from api/src/com/cloud/storage/ObjectStore.java rename to api/src/com/cloud/storage/ImageStore.java index 636537f8437..54d22d10f3f 100644 --- a/api/src/com/cloud/storage/ObjectStore.java +++ b/api/src/com/cloud/storage/ImageStore.java @@ -19,7 +19,12 @@ package com.cloud.storage; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -public interface ObjectStore extends Identity, InternalIdentity { +public interface ImageStore extends Identity, InternalIdentity { + + public enum State { + Disabled, Enabled, Deactivated; + } + /** * @return name of the object store. @@ -32,10 +37,9 @@ public interface ObjectStore extends Identity, InternalIdentity { Long getDataCenterId(); /** - * @return region id. - * @return + * @return image store state. */ - Long getRegionId(); + State getState(); /** * @return object store provider name diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index b85f2c5f7ed..3d381b0300a 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -326,7 +326,7 @@ public interface ResponseGenerator { RegionResponse createRegionResponse(Region region); - ObjectStoreResponse createObjectStoreResponse(ObjectStore os); + ImageStoreResponse createImageStoreResponse(ImageStore os); /** * @param resourceTag diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java index 663750edcc8..94aaa5fcc25 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java @@ -25,16 +25,13 @@ 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.HostResponse; -import org.apache.cloudstack.api.response.ObjectStoreResponse; import org.apache.cloudstack.api.response.RegionResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.log4j.Logger; import com.cloud.exception.DiscoveryException; import com.cloud.host.Host; -import com.cloud.storage.ObjectStore; import com.cloud.user.Account; @APICommand(name = "addSecondaryStorage", description="Adds secondary storage.", responseObject=HostResponse.class) @@ -113,14 +110,17 @@ public class AddSecondaryStorageCmd extends BaseCmd { @Override public void execute(){ - try{ - ObjectStore result = _resourceService.discoverObjectStore(this); - ObjectStoreResponse storeResponse = null; - if (result != null ) { - storeResponse = _responseGenerator.createObjectStoreResponse(result); - storeResponse.setResponseName(getCommandName()); - storeResponse.setObjectName("secondarystorage"); - this.setResponseObject(storeResponse); + try { + List result = _resourceService.discoverHosts(this); + HostResponse hostResponse = null; + if (result != null && result.size() > 0) { + for (Host host : result) { + // There should only be one secondary storage host per add + hostResponse = _responseGenerator.createHostResponse(host); + hostResponse.setResponseName(getCommandName()); + hostResponse.setObjectName("secondarystorage"); + this.setResponseObject(hostResponse); + } } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage"); } @@ -128,5 +128,6 @@ public class AddSecondaryStorageCmd extends BaseCmd { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); } + } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java new file mode 100644 index 00000000000..40ae6b26e84 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -0,0 +1,120 @@ +// 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.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 = "addImageStore", description="Adds backup image store.", responseObject=ImageStoreResponse.class) +public class AddImageStoreCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(AddImageStoreCmd.class.getName()); + private static final String s_name = "addimagestoreresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=true, description="the URL for the image 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 details; + + @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, + required=false, description="the scope of the image store: zone or region") + private String scope; + + @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, + required=false, description="the image store provider name") + private String providerName; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getUrl() { + return url; + } + + public Long getZoneId() { + return zoneId; + } + + public Map 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 = _resourceService.discoverImageStore(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 (DiscoveryException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); + } + } +} diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java b/api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java similarity index 88% rename from api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java rename to api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java index 74a42f2612a..6f90f0ff8f7 100644 --- a/api/src/org/apache/cloudstack/api/response/ObjectStoreDetailResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ImageStoreDetailResponse.java @@ -21,18 +21,18 @@ import org.apache.cloudstack.api.BaseResponse; import com.cloud.serializer.Param; import com.google.gson.annotations.SerializedName; -public class ObjectStoreDetailResponse extends BaseResponse { - @SerializedName("name") @Param(description="detail property name of the object store") +public class ImageStoreDetailResponse extends BaseResponse { + @SerializedName("name") @Param(description="detail property name of the image store") private String name; - @SerializedName("value") @Param(description="detail property value of the object store") + @SerializedName("value") @Param(description="detail property value of the image store") private String value; - public ObjectStoreDetailResponse(){ + public ImageStoreDetailResponse(){ super(); } - public ObjectStoreDetailResponse(String name, String val){ + public ImageStoreDetailResponse(String name, String val){ super(); this.name = name; this.value = val; @@ -71,7 +71,7 @@ public class ObjectStoreDetailResponse extends BaseResponse { return false; if (getClass() != obj.getClass()) return false; - ObjectStoreDetailResponse other = (ObjectStoreDetailResponse) obj; + ImageStoreDetailResponse other = (ImageStoreDetailResponse) obj; String oid = this.getName(); if (oid == null) { if (other.getName() != null) diff --git a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java b/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java similarity index 70% rename from api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java rename to api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java index 595ae9732e0..21dc635a09c 100644 --- a/api/src/org/apache/cloudstack/api/response/ObjectStoreResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java @@ -24,48 +24,46 @@ import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.EntityReference; import com.cloud.serializer.Param; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import com.google.gson.annotations.SerializedName; -@EntityReference(value=ObjectStore.class) -public class ObjectStoreResponse extends BaseResponse { - @SerializedName("id") @Param(description="the ID of the object store") +@EntityReference(value=ImageStore.class) +public class ImageStoreResponse extends BaseResponse { + @SerializedName("id") @Param(description="the ID of the image store") private String id; - @SerializedName("zoneid") @Param(description="the Zone ID of the object store") + @SerializedName("zoneid") @Param(description="the Zone ID of the image store") private String zoneId; - @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the object store") + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the image store") private String zoneName; - @SerializedName("regionid") @Param(description="the Region ID of the object store") - private Long regionId; + @SerializedName("state") @Param(description="the state of the image store") + private ImageStore.State state; - @SerializedName("regionname") @Param(description="the Region name of the object store") - private String regionName; - @SerializedName("name") @Param(description="the name of the object store") + @SerializedName("name") @Param(description="the name of the image store") private String name; - @SerializedName("url") @Param(description="the url of the object store") + @SerializedName("url") @Param(description="the url of the image store") private String url; - @SerializedName("protocol") @Param(description="the protocol of the object store") + @SerializedName("protocol") @Param(description="the protocol of the image store") private String protocol; - @SerializedName("providername") @Param(description="the provider name of the object store") + @SerializedName("providername") @Param(description="the provider name of the image store") private String providerName; - @SerializedName("scope") @Param(description="the scope of the object store") + @SerializedName("scope") @Param(description="the scope of the image store") private ScopeType scope; - @SerializedName("details") @Param(description="the details of the object store") - private Set details; + @SerializedName("details") @Param(description="the details of the image store") + private Set details; - public ObjectStoreResponse(){ - this.details = new LinkedHashSet(); + public ImageStoreResponse(){ + this.details = new LinkedHashSet(); } @Override @@ -98,20 +96,12 @@ public class ObjectStoreResponse extends BaseResponse { } - public Long getRegionId() { - return regionId; + public ImageStore.State getState() { + return state; } - public void setRegionId(Long regionId) { - this.regionId = regionId; - } - - public String getRegionName() { - return regionName; - } - - public void setRegionName(String regionName) { - this.regionName = regionName; + public void setState(ImageStore.State state) { + this.state = state; } public String getName() { @@ -155,15 +145,15 @@ public class ObjectStoreResponse extends BaseResponse { this.protocol = protocol; } - public Set getDetails() { + public Set getDetails() { return details; } - public void setDetails(Set details) { + public void setDetails(Set details) { this.details = details; } - public void addDetail(ObjectStoreDetailResponse detail){ + public void addDetail(ImageStoreDetailResponse detail){ this.details.add(detail); } diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 7b752f0b08a..7bf45a24715 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -786,6 +786,9 @@ + + + diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 163c2cee861..ad17c1512d4 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -241,6 +241,9 @@ listSwifts=1 addS3=1 listS3s=1 +#### image store commands +addImageStore=1 + #### host commands addHost=3 addCluster=1 diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java index 280e02e2a32..2440bfdb197 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java @@ -29,7 +29,7 @@ public interface DataStoreLifeCycle { public boolean attachCluster(DataStore store, ClusterScope scope); public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo); boolean attachZone(DataStore dataStore, ZoneScope scope); - + public boolean dettach(); public boolean unmanaged(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java similarity index 92% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataStoreProvider.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index 1fb987e81cd..9a1f69f3a5b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java @@ -19,6 +19,6 @@ package org.apache.cloudstack.engine.subsystem.api.storage; -public interface ImageDataStoreProvider extends DataStoreProvider { +public interface ImageStoreProvider extends DataStoreProvider { } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreProviderManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java similarity index 57% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreProviderManagerImpl.java rename to engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java index 4430267c700..7ea68dc731f 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataStoreProviderManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageStoreProviderManagerImpl.java @@ -28,38 +28,38 @@ 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.ImageDataStoreProvider; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -import org.apache.cloudstack.storage.image.datastore.ImageDataStore; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; -import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; -import org.apache.cloudstack.storage.image.store.ImageDataStoreImpl; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; +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.db.ImageStoreDao; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.springframework.stereotype.Component; import com.cloud.storage.dao.VMTemplateDao; @Component -public class ImageDataStoreProviderManagerImpl implements ImageDataStoreProviderManager { +public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager { @Inject - ImageDataStoreDao dataStoreDao; + ImageStoreDao dataStoreDao; @Inject VMTemplateDao imageDataDao; @Inject DataStoreProviderManager providerManager; - Map driverMaps; + Map driverMaps; @PostConstruct public void config() { - driverMaps = new HashMap(); + driverMaps = new HashMap(); } @Override - public ImageDataStore getImageDataStore(long dataStoreId) { - ImageDataStoreVO dataStore = dataStoreDao.findById(dataStoreId); + public ImageStoreEntity getImageStore(long dataStoreId) { + ImageStoreVO dataStore = dataStoreDao.findById(dataStoreId); String providerName = dataStore.getProviderName(); - ImageDataStoreProvider provider = (ImageDataStoreProvider)providerManager.getDataStoreProvider(providerName); - ImageDataStore imgStore = ImageDataStoreImpl.getDataStore(dataStore, + ImageStoreProvider provider = (ImageStoreProvider)providerManager.getDataStoreProvider(providerName); + ImageStoreEntity imgStore = ImageStoreImpl.getDataStore(dataStore, driverMaps.get(provider.getName()), provider ); // TODO Auto-generated method stub @@ -67,7 +67,7 @@ public class ImageDataStoreProviderManagerImpl implements ImageDataStoreProvider } @Override - public boolean registerDriver(String providerName, ImageDataStoreDriver driver) { + public boolean registerDriver(String providerName, ImageStoreDriver driver) { if (driverMaps.containsKey(providerName)) { return false; } @@ -76,17 +76,17 @@ public class ImageDataStoreProviderManagerImpl implements ImageDataStoreProvider } @Override - public ImageDataStore getImageDataStore(String uuid) { - ImageDataStoreVO dataStore = dataStoreDao.findByUuid(uuid); - return getImageDataStore(dataStore.getId()); + public ImageStoreEntity getImageStore(String uuid) { + ImageStoreVO dataStore = dataStoreDao.findByUuid(uuid); + return getImageStore(dataStore.getId()); } @Override public List getList() { - List stores = dataStoreDao.listAll(); + List stores = dataStoreDao.listAll(); List imageStores = new ArrayList(); - for (ImageDataStoreVO store : stores) { - imageStores.add(getImageDataStore(store.getId())); + for (ImageStoreVO store : stores) { + imageStores.add(getImageStore(store.getId())); } return imageStores; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java similarity index 80% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java rename to engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 4a6016c699d..60c71f0ffa5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageDataStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -25,46 +25,47 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; +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.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -import org.apache.cloudstack.storage.image.datastore.ImageDataStore; -import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import com.cloud.storage.ImageStore; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.storage.encoding.EncodingType; -public class ImageDataStoreImpl implements ImageDataStore { +public class ImageStoreImpl implements ImageStoreEntity { @Inject VMTemplateDao imageDao; @Inject private ObjectInDataStoreManager objectInStoreMgr; - protected ImageDataStoreDriver driver; - protected ImageDataStoreVO imageDataStoreVO; - protected ImageDataStoreProvider provider; + protected ImageStoreDriver driver; + protected ImageStoreVO imageDataStoreVO; + protected ImageStoreProvider provider; boolean needDownloadToCacheStorage = false; - public ImageDataStoreImpl() { + public ImageStoreImpl() { } - protected void configure(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, - ImageDataStoreProvider provider) { + protected void configure(ImageStoreVO dataStoreVO, ImageStoreDriver imageDataStoreDriver, + ImageStoreProvider provider) { this.driver = imageDataStoreDriver; this.imageDataStoreVO = dataStoreVO; this.provider = provider; } - public static ImageDataStore getDataStore(ImageDataStoreVO dataStoreVO, ImageDataStoreDriver imageDataStoreDriver, - ImageDataStoreProvider provider) { - ImageDataStoreImpl instance = (ImageDataStoreImpl)ComponentContext.inject(ImageDataStoreImpl.class); + public static ImageStoreEntity getDataStore(ImageStoreVO dataStoreVO, ImageStoreDriver imageDataStoreDriver, + ImageStoreProvider provider) { + ImageStoreImpl instance = (ImageStoreImpl)ComponentContext.inject(ImageStoreImpl.class); instance.configure(dataStoreVO, imageDataStoreDriver, provider); return instance; } @@ -154,8 +155,8 @@ public class ImageDataStoreImpl implements ImageDataStore { } @Override - public Long getRegionId() { - return imageDataStoreVO.getRegionId(); + public ImageStore.State getState() { + return imageDataStoreVO.getState(); } @Override diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageDataStoreLifeCycle.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java similarity index 93% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageDataStoreLifeCycle.java rename to engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java index a36823959df..121f8c544ca 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageDataStoreLifeCycle.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/lifecycle/ImageStoreLifeCycle.java @@ -20,5 +20,5 @@ package org.apache.cloudstack.storage.image.store.lifecycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; -public interface ImageDataStoreLifeCycle extends DataStoreLifeCycle { +public interface ImageStoreLifeCycle extends DataStoreLifeCycle { } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index 2d6b94fdfaf..71f1beb3365 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -22,7 +22,7 @@ import java.util.UUID; import javax.inject.Inject; -import org.apache.cloudstack.storage.to.ImageDataStoreTO; +import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.TemplateTO; @@ -131,7 +131,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { Mockito.when(primaryStore.getUuid()).thenReturn(this.getLocalStorageUuid()); Mockito.when(image.getPrimaryDataStore()).thenReturn(primaryStore); - ImageDataStoreTO imageStore = Mockito.mock(ImageDataStoreTO.class); + ImageStoreTO imageStore = Mockito.mock(ImageStoreTO.class); Mockito.when(imageStore.getType()).thenReturn("http"); TemplateTO template = Mockito.mock(TemplateTO.class); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 80e48a2d8f1..8c22767377a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -27,7 +27,7 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.springframework.stereotype.Component; import com.cloud.utils.exception.CloudRuntimeException; @@ -37,14 +37,14 @@ public class DataStoreManagerImpl implements DataStoreManager { @Inject PrimaryDataStoreProviderManager primaryStorMgr; @Inject - ImageDataStoreProviderManager imageDataStoreMgr; + ImageStoreProviderManager imageDataStoreMgr; @Override public DataStore getDataStore(long storeId, DataStoreRole role) { if (role == DataStoreRole.Primary) { return primaryStorMgr.getPrimaryDataStore(storeId); } else if (role == DataStoreRole.Image) { - return imageDataStoreMgr.getImageDataStore(storeId); + return imageDataStoreMgr.getImageStore(storeId); } throw new CloudRuntimeException("un recognized type" + role); } @@ -58,7 +58,7 @@ public class DataStoreManagerImpl implements DataStoreManager { if (role == DataStoreRole.Primary) { return primaryStorMgr.getPrimaryDataStore(uuid); } else if (role == DataStoreRole.Image) { - return imageDataStoreMgr.getImageDataStore(uuid); + return imageDataStoreMgr.getImageStore(uuid); } throw new CloudRuntimeException("un recognized type" + role); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index aa1ace21a76..1bfc5ff02a6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -31,13 +31,13 @@ import org.apache.cloudstack.api.response.StorageProviderResponse; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider.DataStoreProviderType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; +import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -56,7 +56,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Inject PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; @Inject - ImageDataStoreProviderManager imageDataStoreProviderMgr; + ImageStoreProviderManager imageDataStoreProviderMgr; @Override public DataStoreProvider getDataStoreProvider(String name) { return providerMap.get(name); @@ -84,7 +84,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public List getImageDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { - if (provider instanceof ImageDataStoreProvider) { + if (provider instanceof ImageStoreProvider) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.IMAGE.toString()); @@ -123,7 +123,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener()); } else if (types.contains(DataStoreProviderType.IMAGE)) { - imageDataStoreProviderMgr.registerDriver(provider.getName(), (ImageDataStoreDriver)provider.getDataStoreDriver()); + imageDataStoreProviderMgr.registerDriver(provider.getName(), (ImageStoreDriver)provider.getDataStoreDriver()); } } catch(Exception e) { s_logger.debug("configure provider failed", e); @@ -142,7 +142,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Override public DataStoreProvider getDefaultImageDataStoreProvider() { - return this.getDataStoreProvider("cloudstack image data store provider"); + return this.getDataStoreProvider("cloudstack image store provider"); } @Override diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataStoreDriver.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java similarity index 93% rename from engine/storage/src/org/apache/cloudstack/storage/image/ImageDataStoreDriver.java rename to engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java index d352d972182..712e1867523 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageDataStoreDriver.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java @@ -20,5 +20,5 @@ package org.apache.cloudstack.storage.image; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; -public interface ImageDataStoreDriver extends DataStoreDriver { +public interface ImageStoreDriver extends DataStoreDriver { } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java index 4d162bbdd09..51c8c439fc2 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java @@ -25,7 +25,7 @@ import java.util.Map; import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreInfo; +import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.ImageFormat; @@ -38,12 +38,12 @@ public class TemplateEntityImpl implements TemplateEntity { this.templateInfo = templateInfo; } - public ImageDataStoreInfo getImageDataStore() { - return (ImageDataStoreInfo)templateInfo.getDataStore(); + public ImageStoreInfo getImageDataStore() { + return (ImageStoreInfo)templateInfo.getDataStore(); } public long getImageDataStoreId() { - return getImageDataStore().getImageDataStoreId(); + return getImageDataStore().getImageStoreId(); } public TemplateInfo getTemplateInfo() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java deleted file mode 100644 index e31a644d1c9..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreHelper.java +++ /dev/null @@ -1,61 +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.image.datastore; - -import java.util.Map; - -import javax.inject.Inject; - -import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; -import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; -import org.springframework.stereotype.Component; - -import com.cloud.storage.ScopeType; -import com.cloud.utils.exception.CloudRuntimeException; - -@Component -public class ImageDataStoreHelper { - @Inject - ImageDataStoreDao imageStoreDao; - public ImageDataStoreVO createImageDataStore(Map params) { - ImageDataStoreVO store = imageStoreDao.findByName((String)params.get("name")); - if (store != null) { - return store; - } - store = new ImageDataStoreVO(); - store.setName((String)params.get("name")); - store.setProtocol((String)params.get("protocol")); - store.setProviderName((String)params.get("providerName")); - store.setScope((ScopeType)params.get("scope")); - store.setUuid((String)params.get("uuid")); - store.setUrl((String)params.get("url")); - store = imageStoreDao.persist(store); - return store; - } - - public boolean deleteImageDataStore(long id) { - ImageDataStoreVO store = imageStoreDao.findById(id); - if (store == null) { - throw new CloudRuntimeException("can't find image store:" + id); - } - - imageStoreDao.remove(id); - return true; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java similarity index 93% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java rename to engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java index a9b7e9bc5aa..fb1b1d7df2c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStore.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java @@ -26,9 +26,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; -public interface ImageDataStore extends DataStore, ObjectStore { +public interface ImageStoreEntity extends DataStore, ImageStore { TemplateInfo getTemplate(long templateId); VolumeInfo getVolume(long volumeId); SnapshotInfo getSnapshot(long snapshotId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java new file mode 100644 index 00000000000..30ebd1d1b83 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -0,0 +1,99 @@ +/* + * 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.datastore; + +import java.util.Iterator; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.storage.image.db.ImageStoreDao; +import org.apache.cloudstack.storage.image.db.ImageStoreDetailVO; +import org.apache.cloudstack.storage.image.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.springframework.stereotype.Component; + +import com.cloud.storage.ImageStore; +import com.cloud.storage.ScopeType; +import com.cloud.utils.exception.CloudRuntimeException; + +@Component +public class ImageStoreHelper { + @Inject + ImageStoreDao imageStoreDao; + @Inject + ImageStoreDetailsDao imageStoreDetailsDao; + + public ImageStoreVO createImageStore(Map params) { + ImageStoreVO store = imageStoreDao.findByName((String)params.get("name")); + if (store != null) { + return store; + } + store = new ImageStoreVO(); + store.setName((String)params.get("name")); + store.setProtocol((String)params.get("protocol")); + store.setProviderName((String)params.get("providerName")); + store.setScope((ScopeType)params.get("scope")); + store.setUuid((String)params.get("uuid")); + store.setUrl((String)params.get("url")); + store.setState(ImageStore.State.Disabled); + store = imageStoreDao.persist(store); + return store; + } + + public ImageStoreVO createImageStore(Map params, Map details) { + ImageStoreVO store = imageStoreDao.findByName((String)params.get("name")); + if (store != null) { + return store; + } + store = new ImageStoreVO(); + store.setName((String)params.get("name")); + store.setProtocol((String)params.get("protocol")); + store.setProviderName((String)params.get("providerName")); + store.setScope((ScopeType)params.get("scope")); + store.setUuid((String)params.get("uuid")); + store.setUrl((String)params.get("url")); + store.setState(ImageStore.State.Disabled); + store = imageStoreDao.persist(store); + + // persist details + if (details != null){ + Iterator keyIter = details.keySet().iterator(); + while (keyIter.hasNext()){ + String key = keyIter.next(); + ImageStoreDetailVO detail = new ImageStoreDetailVO(); + detail.setStoreId(store.getId()); + detail.setName(key); + detail.setValue(details.get(key)); + imageStoreDetailsDao.persist(detail); + } + } + return store; + } + + public boolean deleteImageStore(long id) { + ImageStoreVO store = imageStoreDao.findById(id); + if (store == null) { + throw new CloudRuntimeException("can't find image store:" + id); + } + + imageStoreDao.remove(id); + return true; + } +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreInfo.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java similarity index 91% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreInfo.java rename to engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java index b6b9a2a55d7..c5f7ca98c1d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreInfo.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java @@ -20,7 +20,7 @@ package org.apache.cloudstack.storage.image.datastore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -public interface ImageDataStoreInfo extends DataStore { - public long getImageDataStoreId(); +public interface ImageStoreInfo extends DataStore { + public long getImageStoreId(); public String getType(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java similarity index 77% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreProviderManager.java rename to engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index 4ab3f3c19d8..d9a733d300f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageDataStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -21,11 +21,11 @@ package org.apache.cloudstack.storage.image.datastore; import java.util.List; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; +import org.apache.cloudstack.storage.image.ImageStoreDriver; -public interface ImageDataStoreProviderManager { - ImageDataStore getImageDataStore(long dataStoreId); - ImageDataStore getImageDataStore(String uuid); +public interface ImageStoreProviderManager { + ImageStoreEntity getImageStore(long dataStoreId); + ImageStoreEntity getImageStore(String uuid); List getList(); - boolean registerDriver(String uuid, ImageDataStoreDriver driver); + boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDao.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDao.java deleted file mode 100644 index 1b13b7ae4e2..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDao.java +++ /dev/null @@ -1,25 +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.image.db; - -import com.cloud.utils.db.GenericDao; - -public interface ImageDataStoreProviderDao extends GenericDao { - public ImageDataStoreProviderVO findByName(String name); -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDaoImpl.java deleted file mode 100644 index 0e19dbec1b7..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderDaoImpl.java +++ /dev/null @@ -1,40 +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.image.db; - -import org.springframework.stereotype.Component; - -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.SearchCriteria.Op; - -@Component -public class ImageDataStoreProviderDaoImpl extends GenericDaoBase implements ImageDataStoreProviderDao { - - public ImageDataStoreProviderDaoImpl() { - } - - @Override - public ImageDataStoreProviderVO findByName(String name) { - SearchCriteriaService service = SearchCriteria2.create(ImageDataStoreProviderVO.class); - service.addAnd(service.getEntity().getName(), Op.EQ, name); - return service.find(); - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderVO.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderVO.java deleted file mode 100644 index 5cc5b8ddcef..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreProviderVO.java +++ /dev/null @@ -1,49 +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.image.db; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.TableGenerator; - -@Entity -@Table(name = "image_data_store_provider") -public class ImageDataStoreProviderVO { - @Id - @TableGenerator(name = "image_data_store_provider_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "image_data_store_provider_seq", allocationSize = 1) - @Column(name = "id", nullable = false) - private long id; - - @Column(name = "name", nullable = false) - private String name; - - public long getId() { - return this.id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDao.java similarity index 87% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreDao.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDao.java index d7358be9140..18841bc16e2 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreDao.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDao.java @@ -20,6 +20,6 @@ package org.apache.cloudstack.storage.image.db; import com.cloud.utils.db.GenericDao; -public interface ImageDataStoreDao extends GenericDao { - public ImageDataStoreVO findByName(String name); +public interface ImageStoreDao extends GenericDao { + public ImageStoreVO findByName(String name); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDaoStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java similarity index 80% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDaoStoreDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 3f3e9ca95fb..60d414c893d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDaoStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -26,11 +26,11 @@ import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.db.SearchCriteria.Op; @Component -public class ImageDaoStoreDaoImpl extends GenericDaoBase implements ImageDataStoreDao { +public class ImageStoreDaoImpl extends GenericDaoBase implements ImageStoreDao { @Override - public ImageDataStoreVO findByName(String name) { - SearchCriteriaService sc = SearchCriteria2.create(ImageDataStoreVO.class); + public ImageStoreVO findByName(String name) { + SearchCriteriaService sc = SearchCriteria2.create(ImageStoreVO.class); sc.addAnd(sc.getEntity().getName(), Op.EQ, name); return sc.find(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java similarity index 87% rename from engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java index c980cf15693..3afddaa9c24 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.datastore.db; +package org.apache.cloudstack.storage.image.db; import org.apache.cloudstack.api.InternalIdentity; @@ -26,8 +26,8 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="image_data_store_details") -public class ImageDataStoreDetailVO implements InternalIdentity { +@Table(name="image_store_details") +public class ImageStoreDetailVO implements InternalIdentity { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") @@ -42,7 +42,10 @@ public class ImageDataStoreDetailVO implements InternalIdentity { @Column(name="value") String value; - public ImageDataStoreDetailVO(long storeId, String name, String value) { + public ImageStoreDetailVO() { + } + + public ImageStoreDetailVO(long storeId, String name, String value) { this.storeId = storeId; this.name = name; this.value = value; @@ -76,6 +79,5 @@ public class ImageDataStoreDetailVO implements InternalIdentity { this.value = value; } - protected ImageDataStoreDetailVO() { - } + } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java similarity index 87% rename from engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java index 781efcfb95e..98672904d54 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageDataStoreDetailsDao.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java @@ -14,14 +14,14 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.datastore.db; +package org.apache.cloudstack.storage.image.db; import java.util.Map; import com.cloud.utils.db.GenericDao; -public interface ImageDataStoreDetailsDao extends GenericDao { +public interface ImageStoreDetailsDao extends GenericDao { void update(long storeId, Map details); Map getDetails(long storeId); diff --git a/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java similarity index 70% rename from server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java index 1b3fa46b042..e96d6fd93dc 100644 --- a/server/src/com/cloud/storage/dao/ImageDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.storage.dao; +package org.apache.cloudstack.storage.image.db; import java.util.HashMap; import java.util.List; @@ -22,8 +22,6 @@ import java.util.Map; import javax.ejb.Local; -import org.apache.cloudstack.storage.datastore.db.ImageDataStoreDetailVO; -import org.apache.cloudstack.storage.datastore.db.ImageDataStoreDetailsDao; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; @@ -32,12 +30,12 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @Component -@Local(value=ImageDataStoreDetailsDao.class) -public class ImageDataStoreDaoImpl extends GenericDaoBase implements ImageDataStoreDetailsDao { +@Local(value=ImageStoreDetailsDao.class) +public class ImageStoreDetailsDaoImpl extends GenericDaoBase implements ImageStoreDetailsDao { - protected final SearchBuilder storeSearch; + protected final SearchBuilder storeSearch; - protected ImageDataStoreDaoImpl() { + protected ImageStoreDetailsDaoImpl() { super(); storeSearch = createSearchBuilder(); storeSearch.and("store", storeSearch.entity().getStoreId(), SearchCriteria.Op.EQ); @@ -47,13 +45,13 @@ public class ImageDataStoreDaoImpl extends GenericDaoBase details) { Transaction txn = Transaction.currentTxn(); - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = storeSearch.create(); sc.setParameters("store", storeId); txn.start(); expunge(sc); for (Map.Entry entry : details.entrySet()) { - ImageDataStoreDetailVO detail = new ImageDataStoreDetailVO(storeId, entry.getKey(), entry.getValue()); + ImageStoreDetailVO detail = new ImageStoreDetailVO(storeId, entry.getKey(), entry.getValue()); persist(detail); } txn.commit(); @@ -61,12 +59,12 @@ public class ImageDataStoreDaoImpl extends GenericDaoBase getDetails(long storeId) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = storeSearch.create(); sc.setParameters("store", storeId); - List details = listBy(sc); + List details = listBy(sc); Map detailsMap = new HashMap(); - for (ImageDataStoreDetailVO detail : details) { + for (ImageStoreDetailVO detail : details) { detailsMap.put(detail.getName(), detail.getValue()); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreVO.java similarity index 74% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreVO.java index 3e0d8386d9c..36d05e56011 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreVO.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.storage.image.db; +import java.util.Date; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; @@ -27,14 +29,16 @@ import javax.persistence.Table; import javax.persistence.TableGenerator; -import com.cloud.storage.ObjectStore; + +import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; +import com.cloud.utils.db.GenericDao; @Entity -@Table(name = "image_data_store") -public class ImageDataStoreVO implements ObjectStore { +@Table(name = "image_store") +public class ImageStoreVO implements ImageStore { @Id - @TableGenerator(name = "image_data_store_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "image_data_store_seq", allocationSize = 1) + @TableGenerator(name = "image_store_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "image_store_seq", allocationSize = 1) @Column(name = "id", nullable = false) private long id; @@ -56,13 +60,19 @@ public class ImageDataStoreVO implements ObjectStore { @Column(name = "data_center_id") private long dcId; - @Column(name = "region_id") - private long regionId; + @Column(name = "state") + @Enumerated(value = EnumType.STRING) + private State state; @Column(name = "scope") @Enumerated(value = EnumType.STRING) private ScopeType scope; + @Column(name=GenericDao.CREATED_COLUMN) + private Date created; + + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; public long getId() { return this.id; @@ -100,15 +110,6 @@ public class ImageDataStoreVO implements ObjectStore { return this.dcId; } - - public Long getRegionId() { - return regionId; - } - - public void setRegionId(long regionId) { - this.regionId = regionId; - } - public ScopeType getScope() { return this.scope; } @@ -133,5 +134,30 @@ public class ImageDataStoreVO implements ObjectStore { this.url = url; } + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java similarity index 87% rename from engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java rename to engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java index b1de88f0e2a..eb6d0883835 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -16,12 +16,12 @@ // under the License. package org.apache.cloudstack.storage.to; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreInfo; +import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; -public class ImageDataStoreTO { +public class ImageStoreTO { private final String type; private final String uri; - public ImageDataStoreTO(ImageDataStoreInfo dataStore) { + public ImageStoreTO(ImageStoreInfo dataStore) { this.type = dataStore.getType(); this.uri = dataStore.getUri(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java index bc55ea8c3ea..d7b146bd0bc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java @@ -18,19 +18,19 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreInfo; +import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; public class TemplateTO { private final String path; private final String uuid; private DiskFormat diskType; - private final ImageDataStoreTO imageDataStore; + private final ImageStoreTO imageDataStore; public TemplateTO(TemplateInfo template) { this.path = null; this.uuid = template.getUuid(); //this.diskType = template.getDiskType(); - this.imageDataStore = new ImageDataStoreTO((ImageDataStoreInfo)template.getDataStore()); + this.imageDataStore = new ImageStoreTO((ImageStoreInfo)template.getDataStore()); } public String getPath() { @@ -45,7 +45,7 @@ public class TemplateTO { return this.diskType; } - public ImageDataStoreTO getImageDataStore() { + public ImageStoreTO getImageDataStore() { return this.imageDataStore; } } diff --git a/plugins/pom.xml b/plugins/pom.xml index a4f37bb1cb6..1691549db8a 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -58,6 +58,7 @@ user-authenticators/sha256salted network-elements/dns-notifier storage/image/s3 + storage/image/swift storage/image/default storage/image/sample storage/volume/solidfire diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java similarity index 97% rename from plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java rename to plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 1ff395cbecf..e55f0d75749 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageDataStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -33,7 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; +import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -64,9 +64,9 @@ import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.utils.exception.CloudRuntimeException; -public class CloudStackImageDataStoreDriverImpl implements ImageDataStoreDriver { +public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { private static final Logger s_logger = Logger - .getLogger(CloudStackImageDataStoreDriverImpl.class); + .getLogger(CloudStackImageStoreDriverImpl.class); @Inject VMTemplateZoneDao templateZoneDao; @Inject diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java similarity index 84% rename from plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java rename to plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java index f111dfaf8df..fbd9909150a 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageDataStoreLifeCycle.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java @@ -29,11 +29,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; -import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; -import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.db.ImageStoreDao; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; import com.cloud.agent.api.StoragePoolInfo; @@ -49,18 +49,18 @@ import com.cloud.resource.ServerResource; import com.cloud.storage.ScopeType; import com.cloud.utils.UriUtils; -public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { +public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { private static final Logger s_logger = Logger - .getLogger(CloudStackImageDataStoreLifeCycle.class); + .getLogger(CloudStackImageStoreLifeCycleImpl.class); @Inject protected ResourceManager _resourceMgr; @Inject - protected ImageDataStoreDao imageStoreDao; + protected ImageStoreDao imageStoreDao; @Inject - ImageDataStoreHelper imageStoreHelper; + ImageStoreHelper imageStoreHelper; @Inject - ImageDataStoreProviderManager imageStoreMgr; + ImageStoreProviderManager imageStoreMgr; protected List _discoverers; public List getDiscoverers() { @@ -70,7 +70,7 @@ public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycl this._discoverers = _discoverers; } - public CloudStackImageDataStoreLifeCycle() { + public CloudStackImageStoreLifeCycleImpl() { } @@ -80,6 +80,7 @@ public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycl Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); String providerName = (String)dsInfos.get("providerName"); + Map details = (Map)dsInfos.get("details"); s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); @@ -112,11 +113,11 @@ public class CloudStackImageDataStoreLifeCycle implements ImageDataStoreLifeCycl imageStoreParameters.put("zoneId", dcId); imageStoreParameters.put("url", url); imageStoreParameters.put("protocol", uri.getScheme().toLowerCase()); - imageStoreParameters.put("scope", ScopeType.ZONE); + imageStoreParameters.put("scope", ScopeType.ZONE); // default cloudstack provider only supports zone-wide image store imageStoreParameters.put("providerName", providerName); - ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(imageStoreParameters); - return imageStoreMgr.getImageDataStore(ids.getId()); + ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters, details); + return imageStoreMgr.getImageStore(ids.getId()); } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java similarity index 60% rename from plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java rename to plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index 1e88da3f583..058dd27a039 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageDataStoreProvider.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -18,39 +18,35 @@ */ package org.apache.cloudstack.storage.datastore.provider; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.UUID; - import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; -import org.apache.cloudstack.storage.datastore.driver.CloudStackImageDataStoreDriverImpl; -import org.apache.cloudstack.storage.datastore.lifecycle.CloudStackImageDataStoreLifeCycle; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; -import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; +import org.apache.cloudstack.storage.datastore.driver.CloudStackImageStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.CloudStackImageStoreLifeCycleImpl; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.springframework.stereotype.Component; -import com.cloud.storage.ScopeType; import com.cloud.utils.component.ComponentContext; @Component -public class CloudStackImageDataStoreProvider implements ImageDataStoreProvider { +public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { - private final String name = "cloudstack image data store provider"; - protected ImageDataStoreLifeCycle lifeCycle; - protected ImageDataStoreDriver driver; + private final String providerName = "cloudstack image store provider"; + protected ImageStoreLifeCycle lifeCycle; + protected ImageStoreDriver driver; @Inject - ImageDataStoreProviderManager storeMgr; + ImageStoreProviderManager storeMgr; @Inject - ImageDataStoreHelper helper; + ImageStoreHelper helper; @Override public DataStoreLifeCycle getDataStoreLifeCycle() { @@ -59,25 +55,16 @@ public class CloudStackImageDataStoreProvider implements ImageDataStoreProvider @Override public String getName() { - return this.name; + return this.providerName; } @Override public boolean configure(Map params) { - lifeCycle = ComponentContext.inject(CloudStackImageDataStoreLifeCycle.class); - driver = ComponentContext.inject(CloudStackImageDataStoreDriverImpl.class); + lifeCycle = ComponentContext.inject(CloudStackImageStoreLifeCycleImpl.class); + driver = ComponentContext.inject(CloudStackImageStoreDriverImpl.class); storeMgr.registerDriver(this.getName(), driver); - Map infos = new HashMap(); - String dataStoreName = UUID.nameUUIDFromBytes(this.name.getBytes()).toString(); - infos.put("name", dataStoreName); - infos.put("uuid", dataStoreName); - infos.put("protocol", "http"); - infos.put("scope", ScopeType.GLOBAL); - infos.put("providerName", this.getName()); - DataStoreLifeCycle lifeCycle = this.getDataStoreLifeCycle(); - lifeCycle.initialize(infos); return true; } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java new file mode 100644 index 00000000000..c9e85217d99 --- /dev/null +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -0,0 +1,250 @@ +/* + * 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.datastore.driver; + +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.to.S3TO; +import com.cloud.agent.api.to.SwiftTO; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.storage.RegisterVolumePayload; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.storage.VolumeHostVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.dao.VMTemplateZoneDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.storage.swift.SwiftManager; +import com.cloud.utils.exception.CloudRuntimeException; + +public class S3ImageStoreDriverImpl implements ImageStoreDriver { + private static final Logger s_logger = Logger + .getLogger(S3ImageStoreDriverImpl.class); + @Inject + VMTemplateZoneDao templateZoneDao; + @Inject + VMTemplateDao templateDao; + @Inject DownloadMonitor _downloadMonitor; + @Inject + VMTemplateHostDao _vmTemplateHostDao; + @Inject VolumeDao volumeDao; + @Inject VolumeHostDao volumeHostDao; + @Inject HostDao hostDao; + @Inject SnapshotDao snapshotDao; + @Inject AgentManager agentMgr; + @Inject SnapshotManager snapshotMgr; + @Inject + private SwiftManager _swiftMgr; + @Inject + private S3Manager _s3Mgr; + @Override + public String grantAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean revokeAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Set listObjects(DataStore store) { + // TODO Auto-generated method stub + return null; + } + + class CreateContext extends AsyncRpcConext { + final DataObject data; + public CreateContext(AsyncCompletionCallback callback, DataObject data) { + super(callback); + this.data = data; + } + } + + @Override + public void createAsync(DataObject data, + AsyncCompletionCallback callback) { + if (data.getType() == DataObjectType.TEMPLATE) { + List templateZones = this.templateZoneDao.listByTemplateId(data.getId()); + for (VMTemplateZoneVO templateZone : templateZones) { + VMTemplateVO template = this.templateDao.findById(data.getId()); + _downloadMonitor.downloadTemplateToStorage(template, templateZone.getZoneId()); + } + } else if (data.getType() == DataObjectType.VOLUME) { + VolumeVO vol = this.volumeDao.findById(data.getId()); + VolumeInfo volInfo = (VolumeInfo)data; + RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); + _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); + } + + CreateCmdResult result = new CreateCmdResult(null, null); + callback.complete(result); + } + + private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + VolumeVO vol = volumeDao.findById(data.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Expunging " + vol); + } + + // Find out if the volume is present on secondary storage + VolumeHostVO volumeHost = volumeHostDao.findByVolumeId(vol.getId()); + if (volumeHost != null) { + if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + HostVO ssHost = hostDao.findById(volumeHost.getHostId()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( + ssHost.getStorageUrl(), volumeHost.getInstallPath()); + Answer answer = agentMgr.sendToSecStorage(ssHost, dtCommand); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to delete " + + volumeHost + + " due to " + + ((answer == null) ? "answer is null" : answer + .getDetails())); + return; + } + } else if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + s_logger.debug("Volume: " + vol.getName() + + " is currently being uploaded; cant' delete it."); + throw new CloudRuntimeException( + "Please specify a volume that is not currently being uploaded."); + } + volumeHostDao.remove(volumeHost.getId()); + volumeDao.remove(vol.getId()); + CommandResult result = new CommandResult(); + callback.complete(result); + return; + } + } + + private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + + } + + private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { + Long snapshotId = data.getId(); + SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId); + CommandResult result = new CommandResult(); + if (snapshot == null) { + s_logger.debug("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot "); + result.setResult("Unable to find snapshot: " + snapshotId); + callback.complete(result); + return; + } + + try { + String secondaryStoragePoolUrl = this.snapshotMgr.getSecondaryStorageURL(snapshot); + Long dcId = snapshot.getDataCenterId(); + Long accountId = snapshot.getAccountId(); + Long volumeId = snapshot.getVolumeId(); + + String backupOfSnapshot = snapshot.getBackupSnapshotId(); + if (backupOfSnapshot == null) { + callback.complete(result); + return; + } + SwiftTO swift = _swiftMgr.getSwiftTO(snapshot.getSwiftId()); + S3TO s3 = _s3Mgr.getS3TO(); + + DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( + swift, s3, secondaryStoragePoolUrl, dcId, accountId, volumeId, + backupOfSnapshot, false); + Answer answer = agentMgr.sendToSSVM(dcId, cmd); + + if ((answer != null) && answer.getResult()) { + snapshot.setBackupSnapshotId(null); + snapshotDao.update(snapshotId, snapshot); + } else if (answer != null) { + result.setResult(answer.getDetails()); + } + } catch (Exception e) { + s_logger.debug("failed to delete snapshot: " + snapshotId + ": " + e.toString()); + result.setResult(e.toString()); + } + callback.complete(result); + } + + @Override + public void deleteAsync(DataObject data, + AsyncCompletionCallback callback) { + if (data.getType() == DataObjectType.VOLUME) { + deleteVolume(data, callback); + } else if (data.getType() == DataObjectType.TEMPLATE) { + deleteTemplate(data, callback); + } else if (data.getType() == DataObjectType.SNAPSHOT) { + deleteSnapshot(data, callback); + } + } + + @Override + public void copyAsync(DataObject srcdata, DataObject destData, + AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void resize(DataObject data, + AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + +} diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java new file mode 100644 index 00000000000..7d22df5006b --- /dev/null +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -0,0 +1,177 @@ +// 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.datastore.lifecycle; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.db.ImageStoreDao; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.exception.DiscoveryException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase; +import com.cloud.resource.Discoverer; +import com.cloud.resource.ResourceListener; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ServerResource; +import com.cloud.storage.ScopeType; +import com.cloud.storage.s3.S3Manager; +import com.cloud.utils.UriUtils; + +public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { + + private static final Logger s_logger = Logger + .getLogger(S3ImageStoreLifeCycleImpl.class); + @Inject + protected ResourceManager _resourceMgr; + @Inject + protected ImageStoreDao imageStoreDao; + @Inject + ImageStoreHelper imageStoreHelper; + @Inject + ImageStoreProviderManager imageStoreMgr; + @Inject + S3Manager _s3Mgr; + + protected List _discoverers; + public List getDiscoverers() { + return _discoverers; + } + public void setDiscoverers(List _discoverers) { + this._discoverers = _discoverers; + } + + public S3ImageStoreLifeCycleImpl() { + } + + + @Override + public DataStore initialize(Map dsInfos) { + + Long dcId = (Long) dsInfos.get("zoneId"); + String url = (String) dsInfos.get("url"); + String providerName = (String)dsInfos.get("providerName"); + ScopeType scope = (ScopeType)dsInfos.get("scope"); + Map details = (Map)dsInfos.get("details"); + + s_logger.info("Trying to add a S3 store in data center " + dcId); + + try{ + // verify S3 parameters + _s3Mgr.verifyS3Fields(details); + } + catch (DiscoveryException ex){ + throw new InvalidParameterValueException("failed to verify S3 parameters!"); + } + + Map imageStoreParameters = new HashMap(); + imageStoreParameters.put("name", url); + imageStoreParameters.put("zoneId", dcId); + imageStoreParameters.put("url", url); + String protocol = "http"; + String useHttps = details.get(ApiConstants.S3_HTTPS_FLAG); + if (useHttps != null && Boolean.parseBoolean(useHttps)){ + protocol = "https"; + } + imageStoreParameters.put("protocol", protocol); + if (scope != null) { + imageStoreParameters.put("scope", scope); + } else { + imageStoreParameters.put("scope", ScopeType.REGION); + } + imageStoreParameters.put("providerName", providerName); + + ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters, details); + return imageStoreMgr.getImageStore(ids.getId()); + } + + + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean attachHost(DataStore store, HostScope scope, + StoragePoolInfo existingInfo) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean attachZone(DataStore dataStore, ZoneScope scope) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean dettach() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean unmanaged() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean maintain(DataStore store) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean cancelMaintain(DataStore store) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean deleteDataStore(DataStore store) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java new file mode 100644 index 00000000000..820882dd75a --- /dev/null +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java @@ -0,0 +1,90 @@ +/* + * 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.datastore.provider; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; +import org.apache.cloudstack.storage.datastore.driver.S3ImageStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.S3ImageStoreLifeCycleImpl; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; +import org.springframework.stereotype.Component; + +import com.cloud.storage.ScopeType; +import com.cloud.utils.component.ComponentContext; + +@Component +public class S3ImageStoreProviderImpl implements ImageStoreProvider { + + private final String providerName = "S3 image store provider"; + protected ImageStoreLifeCycle lifeCycle; + protected ImageStoreDriver driver; + @Inject + ImageStoreProviderManager storeMgr; + @Inject + ImageStoreHelper helper; + + @Override + public DataStoreLifeCycle getDataStoreLifeCycle() { + return lifeCycle; + } + + @Override + public String getName() { + return this.providerName; + } + + @Override + public boolean configure(Map params) { + lifeCycle = ComponentContext.inject(S3ImageStoreLifeCycleImpl.class); + driver = ComponentContext.inject(S3ImageStoreDriverImpl.class); + storeMgr.registerDriver(this.getName(), driver); + return true; + } + + @Override + public DataStoreDriver getDataStoreDriver() { + return this.driver; + } + + @Override + public HypervisorHostListener getHostListener() { + return null; + } + + @Override + public Set getTypes() { + Set types = new HashSet(); + types.add(DataStoreProviderType.IMAGE); + return types; + } + +} diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java similarity index 96% rename from plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java rename to plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index cf42ac34da8..dc2e58c99cd 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageDataStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -33,17 +33,17 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.endpoint.EndPointSelector; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; +import org.apache.cloudstack.storage.image.ImageStoreDriver; import com.cloud.storage.dao.VMTemplateDao; //http-read-only based image store -public class SampleImageDataStoreDriverImpl implements ImageDataStoreDriver { +public class SampleImageStoreDriverImpl implements ImageStoreDriver { @Inject EndPointSelector selector; @Inject VMTemplateDao imageDataDao; - public SampleImageDataStoreDriverImpl() { + public SampleImageStoreDriverImpl() { } @Override diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java similarity index 78% rename from plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java rename to plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java index c1e08912718..8c61f036a16 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageDataStoreLifeCycle.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java @@ -24,29 +24,29 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreHelper; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageDataStoreDao; -import org.apache.cloudstack.storage.image.db.ImageDataStoreVO; -import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.db.ImageStoreDao; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import com.cloud.agent.api.StoragePoolInfo; -public class SampleImageDataStoreLifeCycle implements ImageDataStoreLifeCycle { +public class SampleImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Inject - protected ImageDataStoreDao imageStoreDao; + protected ImageStoreDao imageStoreDao; @Inject - ImageDataStoreHelper imageStoreHelper; + ImageStoreHelper imageStoreHelper; @Inject - ImageDataStoreProviderManager imageStoreMgr; - public SampleImageDataStoreLifeCycle() { + ImageStoreProviderManager imageStoreMgr; + public SampleImageStoreLifeCycleImpl() { } @Override public DataStore initialize(Map dsInfos) { - ImageDataStoreVO ids = imageStoreHelper.createImageDataStore(dsInfos); - return imageStoreMgr.getImageDataStore(ids.getId()); + ImageStoreVO ids = imageStoreHelper.createImageStore(dsInfos); + return imageStoreMgr.getImageStore(ids.getId()); } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java similarity index 77% rename from plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java rename to plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index 2ad9602a7bb..073a157cb3d 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageDataStoreProvider.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -27,21 +27,21 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataStoreProvider; -import org.apache.cloudstack.storage.datastore.driver.SampleImageDataStoreDriverImpl; -import org.apache.cloudstack.storage.datastore.lifecycle.SampleImageDataStoreLifeCycle; -import org.apache.cloudstack.storage.image.ImageDataStoreDriver; -import org.apache.cloudstack.storage.image.datastore.ImageDataStoreProviderManager; -import org.apache.cloudstack.storage.image.store.lifecycle.ImageDataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; +import org.apache.cloudstack.storage.datastore.driver.SampleImageStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.SampleImageStoreLifeCycleImpl; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import com.cloud.utils.component.ComponentContext; -public class SampleImageDataStoreProvider implements ImageDataStoreProvider { +public class SampleImageStoreProviderImpl implements ImageStoreProvider { private final String name = "sample image data store provider"; - protected ImageDataStoreLifeCycle lifeCycle; - protected ImageDataStoreDriver driver; + protected ImageStoreLifeCycle lifeCycle; + protected ImageStoreDriver driver; @Inject - ImageDataStoreProviderManager storeMgr; + ImageStoreProviderManager storeMgr; long id; String uuid; @Override @@ -56,8 +56,8 @@ public class SampleImageDataStoreProvider implements ImageDataStoreProvider { @Override public boolean configure(Map params) { - lifeCycle = ComponentContext.inject(SampleImageDataStoreLifeCycle.class); - driver = ComponentContext.inject(SampleImageDataStoreDriverImpl.class); + lifeCycle = ComponentContext.inject(SampleImageStoreLifeCycleImpl.class); + driver = ComponentContext.inject(SampleImageStoreDriverImpl.class); storeMgr.registerDriver(this.getName(), driver); return true; diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml new file mode 100644 index 00000000000..27ebbe5c5e7 --- /dev/null +++ b/plugins/storage/image/swift/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + cloud-plugin-storage-image-swift + Apache CloudStack Plugin - Storage Image Swift provider + + org.apache.cloudstack + cloudstack-plugins + 4.2.0-SNAPSHOT + ../../../pom.xml + + + + org.apache.cloudstack + cloud-engine-storage-image + ${project.version} + + + mysql + mysql-connector-java + ${cs.mysql.version} + provided + + + + install + src + test + + + maven-surefire-plugin + + true + + + + integration-test + + test + + + + + + + diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java new file mode 100644 index 00000000000..168e23a0535 --- /dev/null +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -0,0 +1,250 @@ +/* + * 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.datastore.driver; + +import java.util.List; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.log4j.Logger; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.to.S3TO; +import com.cloud.agent.api.to.SwiftTO; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.storage.RegisterVolumePayload; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.storage.VolumeHostVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VMTemplateHostDao; +import com.cloud.storage.dao.VMTemplateZoneDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.storage.swift.SwiftManager; +import com.cloud.utils.exception.CloudRuntimeException; + +public class SwiftImageStoreDriverImpl implements ImageStoreDriver { + private static final Logger s_logger = Logger + .getLogger(SwiftImageStoreDriverImpl.class); + @Inject + VMTemplateZoneDao templateZoneDao; + @Inject + VMTemplateDao templateDao; + @Inject DownloadMonitor _downloadMonitor; + @Inject + VMTemplateHostDao _vmTemplateHostDao; + @Inject VolumeDao volumeDao; + @Inject VolumeHostDao volumeHostDao; + @Inject HostDao hostDao; + @Inject SnapshotDao snapshotDao; + @Inject AgentManager agentMgr; + @Inject SnapshotManager snapshotMgr; + @Inject + private SwiftManager _swiftMgr; + @Inject + private S3Manager _s3Mgr; + @Override + public String grantAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean revokeAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Set listObjects(DataStore store) { + // TODO Auto-generated method stub + return null; + } + + class CreateContext extends AsyncRpcConext { + final DataObject data; + public CreateContext(AsyncCompletionCallback callback, DataObject data) { + super(callback); + this.data = data; + } + } + + @Override + public void createAsync(DataObject data, + AsyncCompletionCallback callback) { + if (data.getType() == DataObjectType.TEMPLATE) { + List templateZones = this.templateZoneDao.listByTemplateId(data.getId()); + for (VMTemplateZoneVO templateZone : templateZones) { + VMTemplateVO template = this.templateDao.findById(data.getId()); + _downloadMonitor.downloadTemplateToStorage(template, templateZone.getZoneId()); + } + } else if (data.getType() == DataObjectType.VOLUME) { + VolumeVO vol = this.volumeDao.findById(data.getId()); + VolumeInfo volInfo = (VolumeInfo)data; + RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); + _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); + } + + CreateCmdResult result = new CreateCmdResult(null, null); + callback.complete(result); + } + + private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + VolumeVO vol = volumeDao.findById(data.getId()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Expunging " + vol); + } + + // Find out if the volume is present on secondary storage + VolumeHostVO volumeHost = volumeHostDao.findByVolumeId(vol.getId()); + if (volumeHost != null) { + if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + HostVO ssHost = hostDao.findById(volumeHost.getHostId()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( + ssHost.getStorageUrl(), volumeHost.getInstallPath()); + Answer answer = agentMgr.sendToSecStorage(ssHost, dtCommand); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to delete " + + volumeHost + + " due to " + + ((answer == null) ? "answer is null" : answer + .getDetails())); + return; + } + } else if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + s_logger.debug("Volume: " + vol.getName() + + " is currently being uploaded; cant' delete it."); + throw new CloudRuntimeException( + "Please specify a volume that is not currently being uploaded."); + } + volumeHostDao.remove(volumeHost.getId()); + volumeDao.remove(vol.getId()); + CommandResult result = new CommandResult(); + callback.complete(result); + return; + } + } + + private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + + } + + private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { + Long snapshotId = data.getId(); + SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId); + CommandResult result = new CommandResult(); + if (snapshot == null) { + s_logger.debug("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot "); + result.setResult("Unable to find snapshot: " + snapshotId); + callback.complete(result); + return; + } + + try { + String secondaryStoragePoolUrl = this.snapshotMgr.getSecondaryStorageURL(snapshot); + Long dcId = snapshot.getDataCenterId(); + Long accountId = snapshot.getAccountId(); + Long volumeId = snapshot.getVolumeId(); + + String backupOfSnapshot = snapshot.getBackupSnapshotId(); + if (backupOfSnapshot == null) { + callback.complete(result); + return; + } + SwiftTO swift = _swiftMgr.getSwiftTO(snapshot.getSwiftId()); + S3TO s3 = _s3Mgr.getS3TO(); + + DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( + swift, s3, secondaryStoragePoolUrl, dcId, accountId, volumeId, + backupOfSnapshot, false); + Answer answer = agentMgr.sendToSSVM(dcId, cmd); + + if ((answer != null) && answer.getResult()) { + snapshot.setBackupSnapshotId(null); + snapshotDao.update(snapshotId, snapshot); + } else if (answer != null) { + result.setResult(answer.getDetails()); + } + } catch (Exception e) { + s_logger.debug("failed to delete snapshot: " + snapshotId + ": " + e.toString()); + result.setResult(e.toString()); + } + callback.complete(result); + } + + @Override + public void deleteAsync(DataObject data, + AsyncCompletionCallback callback) { + if (data.getType() == DataObjectType.VOLUME) { + deleteVolume(data, callback); + } else if (data.getType() == DataObjectType.TEMPLATE) { + deleteTemplate(data, callback); + } else if (data.getType() == DataObjectType.SNAPSHOT) { + deleteSnapshot(data, callback); + } + } + + @Override + public void copyAsync(DataObject srcdata, DataObject destData, + AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void resize(DataObject data, + AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + +} diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java new file mode 100644 index 00000000000..62dbfaebce8 --- /dev/null +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -0,0 +1,161 @@ +// 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.datastore.lifecycle; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.db.ImageStoreDao; +import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.exception.DiscoveryException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase; +import com.cloud.resource.Discoverer; +import com.cloud.resource.ResourceListener; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ServerResource; +import com.cloud.storage.ScopeType; +import com.cloud.utils.UriUtils; + +public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { + + private static final Logger s_logger = Logger + .getLogger(SwiftImageStoreLifeCycleImpl.class); + @Inject + protected ResourceManager _resourceMgr; + @Inject + protected ImageStoreDao imageStoreDao; + @Inject + ImageStoreHelper imageStoreHelper; + @Inject + ImageStoreProviderManager imageStoreMgr; + + protected List _discoverers; + public List getDiscoverers() { + return _discoverers; + } + public void setDiscoverers(List _discoverers) { + this._discoverers = _discoverers; + } + + public SwiftImageStoreLifeCycleImpl() { + } + + + @Override + public DataStore initialize(Map dsInfos) { + + Long dcId = (Long) dsInfos.get("zoneId"); + String url = (String) dsInfos.get("url"); + ScopeType scope = (ScopeType)dsInfos.get("scope"); + String providerName = (String)dsInfos.get("providerName"); + Map details = (Map)dsInfos.get("details"); + + s_logger.info("Trying to add a swift store at " + url + " in data center " + dcId); + + // just need to insert an entry in DB + Map imageStoreParameters = new HashMap(); + imageStoreParameters.put("name", url); + imageStoreParameters.put("zoneId", dcId); + imageStoreParameters.put("url", url); + imageStoreParameters.put("protocol", "http"); + if (scope != null) { + imageStoreParameters.put("scope", scope); + } else { + imageStoreParameters.put("scope", ScopeType.REGION); + } + imageStoreParameters.put("providerName", providerName); + + ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters); + return imageStoreMgr.getImageStore(ids.getId()); + } + + + @Override + public boolean attachCluster(DataStore store, ClusterScope scope) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean attachHost(DataStore store, HostScope scope, + StoragePoolInfo existingInfo) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean attachZone(DataStore dataStore, ZoneScope scope) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean dettach() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean unmanaged() { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean maintain(DataStore store) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean cancelMaintain(DataStore store) { + // TODO Auto-generated method stub + return false; + } + + + @Override + public boolean deleteDataStore(DataStore store) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java new file mode 100644 index 00000000000..625fcffb7ff --- /dev/null +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java @@ -0,0 +1,92 @@ +/* + * 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.datastore.provider; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; +import org.apache.cloudstack.storage.datastore.driver.SwiftImageStoreDriverImpl; +import org.apache.cloudstack.storage.datastore.lifecycle.SwiftImageStoreLifeCycleImpl; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; +import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; +import org.springframework.stereotype.Component; + +import com.cloud.storage.ScopeType; +import com.cloud.utils.component.ComponentContext; + +@Component +public class SwiftImageStoreProviderImpl implements ImageStoreProvider { + + private final String providerName = "Swift image store provider"; + protected ImageStoreLifeCycle lifeCycle; + protected ImageStoreDriver driver; + @Inject + ImageStoreProviderManager storeMgr; + @Inject + ImageStoreHelper helper; + + @Override + public DataStoreLifeCycle getDataStoreLifeCycle() { + return lifeCycle; + } + + @Override + public String getName() { + return this.providerName; + } + + @Override + public boolean configure(Map params) { + lifeCycle = ComponentContext.inject(SwiftImageStoreLifeCycleImpl.class); + driver = ComponentContext.inject(SwiftImageStoreDriverImpl.class); + + storeMgr.registerDriver(this.getName(), driver); + + return true; + } + + @Override + public DataStoreDriver getDataStoreDriver() { + return this.driver; + } + + @Override + public HypervisorHostListener getHostListener() { + return null; + } + + @Override + public Set getTypes() { + Set types = new HashSet(); + types.add(DataStoreProviderType.IMAGE); + return types; + } + +} diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 41f0759152f..6b8607f6a85 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -34,7 +34,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; import org.apache.cloudstack.api.response.ProjectResponse; @@ -56,7 +56,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; import com.cloud.api.query.dao.DomainRouterJoinDao; import com.cloud.api.query.dao.HostJoinDao; -import com.cloud.api.query.dao.ImageDataStoreJoinDao; +import com.cloud.api.query.dao.ImageStoreJoinDao; import com.cloud.api.query.dao.InstanceGroupJoinDao; import com.cloud.api.query.dao.ProjectAccountJoinDao; import com.cloud.api.query.dao.ProjectInvitationJoinDao; @@ -75,7 +75,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -208,6 +208,7 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; +import com.cloud.storage.ImageStore; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; @@ -365,7 +366,7 @@ public class ApiDBUtils { static HostJoinDao _hostJoinDao; static VolumeJoinDao _volJoinDao; static StoragePoolJoinDao _poolJoinDao; - static ImageDataStoreJoinDao _imageStoreJoinDao; + static ImageStoreJoinDao _imageStoreJoinDao; static AccountJoinDao _accountJoinDao; static AsyncJobJoinDao _jobJoinDao; @@ -470,7 +471,7 @@ public class ApiDBUtils { @Inject private HostJoinDao hostJoinDao; @Inject private VolumeJoinDao volJoinDao; @Inject private StoragePoolJoinDao poolJoinDao; - @Inject private ImageDataStoreJoinDao imageStoreJoinDao; + @Inject private ImageStoreJoinDao imageStoreJoinDao; @Inject private AccountJoinDao accountJoinDao; @Inject private AsyncJobJoinDao jobJoinDao; @@ -1541,16 +1542,16 @@ public class ApiDBUtils { return _poolJoinDao.newStoragePoolView(vr); } - public static ObjectStoreResponse newImageStoreResponse(ImageDataStoreJoinVO vr) { - return _imageStoreJoinDao.newObjectStoreResponse(vr); + public static ImageStoreResponse newImageStoreResponse(ImageStoreJoinVO vr) { + return _imageStoreJoinDao.newImageStoreResponse(vr); } - public static ObjectStoreResponse fillImageStoreDetails(ObjectStoreResponse vrData, ImageDataStoreJoinVO vr){ - return _imageStoreJoinDao.setObjectStoreResponse(vrData, vr); + public static ImageStoreResponse fillImageStoreDetails(ImageStoreResponse vrData, ImageStoreJoinVO vr){ + return _imageStoreJoinDao.setImageStoreResponse(vrData, vr); } - public static List newImageStoreView(ObjectStore vr){ - return _imageStoreJoinDao.newObjectStoreView(vr); + public static List newImageStoreView(ImageStore vr){ + return _imageStoreJoinDao.newImageStoreView(vr); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 03ed97da640..527204556df 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -80,7 +80,7 @@ import org.apache.cloudstack.api.response.NetworkOfferingResponse; import org.apache.cloudstack.api.response.NetworkResponse; import org.apache.cloudstack.api.response.NicResponse; import org.apache.cloudstack.api.response.NicSecondaryIpResponse; -import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.PhysicalNetworkResponse; import org.apache.cloudstack.api.response.PodResponse; import org.apache.cloudstack.api.response.PrivateGatewayResponse; @@ -142,7 +142,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -237,7 +237,7 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; @@ -892,9 +892,9 @@ public class ApiResponseHelper implements ResponseGenerator { @Override - public ObjectStoreResponse createObjectStoreResponse(ObjectStore os) { - List viewStores = ApiDBUtils.newImageStoreView(os); - List listStores = ViewResponseHelper.createObjectStoreResponse(viewStores.toArray(new ImageDataStoreJoinVO[viewStores.size()])); + public ImageStoreResponse createImageStoreResponse(ImageStore os) { + List viewStores = ApiDBUtils.newImageStoreView(os); + List listStores = ViewResponseHelper.createObjectStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()])); assert listStores != null && listStores.size() == 1 : "There should be one image data store returned"; return listStores.get(0); diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index a1d1bf824a1..90b900c57a3 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -30,7 +30,7 @@ import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; -import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; import org.apache.cloudstack.api.response.ProjectInvitationResponse; import org.apache.cloudstack.api.response.ProjectResponse; @@ -52,7 +52,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; -import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -265,11 +265,11 @@ public class ViewResponseHelper { return new ArrayList(vrDataList.values()); } - public static List createObjectStoreResponse(ImageDataStoreJoinVO... stores) { - Hashtable vrDataList = new Hashtable(); + public static List createObjectStoreResponse(ImageStoreJoinVO... stores) { + Hashtable vrDataList = new Hashtable(); // Initialise the vrdatalist with the input data - for (ImageDataStoreJoinVO vr : stores) { - ObjectStoreResponse vrData = vrDataList.get(vr.getId()); + for (ImageStoreJoinVO vr : stores) { + ImageStoreResponse vrData = vrDataList.get(vr.getId()); if ( vrData == null ){ // first time encountering this vm vrData = ApiDBUtils.newImageStoreResponse(vr); @@ -280,7 +280,7 @@ public class ViewResponseHelper { } vrDataList.put(vr.getId(), vrData); } - return new ArrayList(vrDataList.values()); + return new ArrayList(vrDataList.values()); } diff --git a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java b/server/src/com/cloud/api/query/dao/ImageStoreJoinDao.java similarity index 62% rename from server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java rename to server/src/com/cloud/api/query/dao/ImageStoreJoinDao.java index b92fbe60f4b..c1f6325c19b 100644 --- a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDao.java +++ b/server/src/com/cloud/api/query/dao/ImageStoreJoinDao.java @@ -18,19 +18,19 @@ package com.cloud.api.query.dao; import java.util.List; -import org.apache.cloudstack.api.response.ObjectStoreResponse; -import com.cloud.api.query.vo.ImageDataStoreJoinVO; -import com.cloud.storage.ObjectStore; +import org.apache.cloudstack.api.response.ImageStoreResponse; +import com.cloud.api.query.vo.ImageStoreJoinVO; +import com.cloud.storage.ImageStore; import com.cloud.utils.db.GenericDao; -public interface ImageDataStoreJoinDao extends GenericDao { +public interface ImageStoreJoinDao extends GenericDao { - ObjectStoreResponse newObjectStoreResponse(ImageDataStoreJoinVO os); + ImageStoreResponse newImageStoreResponse(ImageStoreJoinVO os); - ObjectStoreResponse setObjectStoreResponse(ObjectStoreResponse response, ImageDataStoreJoinVO os); + ImageStoreResponse setImageStoreResponse(ImageStoreResponse response, ImageStoreJoinVO os); - List newObjectStoreView(ObjectStore os); + List newImageStoreView(ImageStore os); - List searchByIds(Long... spIds); + List searchByIds(Long... spIds); } diff --git a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java similarity index 69% rename from server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java rename to server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java index c58f954e03a..b2fa0c20529 100644 --- a/server/src/com/cloud/api/query/dao/ImageDataStoreJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java @@ -22,33 +22,33 @@ import java.util.List; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.cloudstack.api.response.ObjectStoreDetailResponse; -import org.apache.cloudstack.api.response.ObjectStoreResponse; +import org.apache.cloudstack.api.response.ImageStoreDetailResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.api.query.vo.ImageDataStoreJoinVO; +import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -@Local(value={ImageDataStoreJoinDao.class}) -public class ImageDataStoreJoinDaoImpl extends GenericDaoBase implements ImageDataStoreJoinDao { - public static final Logger s_logger = Logger.getLogger(ImageDataStoreJoinDaoImpl.class); +@Local(value={ImageStoreJoinDao.class}) +public class ImageStoreJoinDaoImpl extends GenericDaoBase implements ImageStoreJoinDao { + public static final Logger s_logger = Logger.getLogger(ImageStoreJoinDaoImpl.class); @Inject private ConfigurationDao _configDao; - private final SearchBuilder dsSearch; + private final SearchBuilder dsSearch; - private final SearchBuilder dsIdSearch; + private final SearchBuilder dsIdSearch; - protected ImageDataStoreJoinDaoImpl() { + protected ImageStoreJoinDaoImpl() { dsSearch = createSearchBuilder(); dsSearch.and("idIN", dsSearch.entity().getId(), SearchCriteria.Op.IN); @@ -66,8 +66,8 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase 0 ){ - ObjectStoreDetailResponse osdResponse = new ObjectStoreDetailResponse(detailName, ids.getDetailValue()); + ImageStoreDetailResponse osdResponse = new ImageStoreDetailResponse(detailName, ids.getDetailValue()); osResponse.addDetail(osdResponse); } - osResponse.setObjectName("objectstore"); + osResponse.setObjectName("imagestore"); return osResponse; } @@ -93,10 +92,10 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase 0 ){ - ObjectStoreDetailResponse osdResponse = new ObjectStoreDetailResponse(detailName, ids.getDetailValue()); + ImageStoreDetailResponse osdResponse = new ImageStoreDetailResponse(detailName, ids.getDetailValue()); response.addDetail(osdResponse); } return response; @@ -105,8 +104,8 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase newObjectStoreView(ObjectStore os) { - SearchCriteria sc = dsIdSearch.create(); + public List newImageStoreView(ImageStore os) { + SearchCriteria sc = dsIdSearch.create(); sc.setParameters("id", os.getId()); return searchIncludingRemoved(sc, null, null, false); @@ -115,7 +114,7 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase searchByIds(Long... spIds) { + public List searchByIds(Long... spIds) { // set detail batch query size int DETAILS_BATCH_SIZE = 2000; String batchCfg = _configDao.getValue("detail.batch.query.size"); @@ -123,7 +122,7 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase uvList = new ArrayList(); + List uvList = new ArrayList(); // query details by batches int curr_index = 0; if ( spIds.length > DETAILS_BATCH_SIZE ){ @@ -132,9 +131,9 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase sc = dsSearch.create(); + SearchCriteria sc = dsSearch.create(); sc.setParameters("idIN", ids); - List vms = searchIncludingRemoved(sc, null, null, false); + List vms = searchIncludingRemoved(sc, null, null, false); if (vms != null) { uvList.addAll(vms); } @@ -148,9 +147,9 @@ public class ImageDataStoreJoinDaoImpl extends GenericDaoBase sc = dsSearch.create(); + SearchCriteria sc = dsSearch.create(); sc.setParameters("idIN", ids); - List vms = searchIncludingRemoved(sc, null, null, false); + List vms = searchIncludingRemoved(sc, null, null, false); if (vms != null) { uvList.addAll(vms); } diff --git a/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java similarity index 87% rename from server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java rename to server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java index 5858dffb148..62c4a8f1a13 100644 --- a/server/src/com/cloud/api/query/vo/ImageDataStoreJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java @@ -22,6 +22,8 @@ import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; + +import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -31,8 +33,8 @@ import org.apache.cloudstack.api.InternalIdentity; * */ @Entity -@Table(name="image_data_store_view") -public class ImageDataStoreJoinVO extends BaseViewVO implements InternalIdentity, Identity { +@Table(name="image_store_view") +public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Identity { @Id @Column(name="id") @@ -66,11 +68,8 @@ public class ImageDataStoreJoinVO extends BaseViewVO implements InternalIdentity @Column(name="data_center_name") private String zoneName; - @Column(name="region_id") - private long regionId; - - @Column(name="region_name") - private String regionName; + @Column(name="state") + private ImageStore.State state; @Column(name="detail_name") private String detailName; @@ -160,20 +159,13 @@ public class ImageDataStoreJoinVO extends BaseViewVO implements InternalIdentity this.scope = scope; } - public long getRegionId() { - return regionId; + + public ImageStore.State getState() { + return state; } - public void setRegionId(long regionId) { - this.regionId = regionId; - } - - public String getRegionName() { - return regionName; - } - - public void setRegionName(String regionName) { - this.regionName = regionName; + public void setState(ImageStore.State state) { + this.state = state; } public void setName(String name) { diff --git a/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java b/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java index bab39907ebe..004ba3dd1e2 100644 --- a/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java +++ b/server/src/com/cloud/api/query/vo/StoragePoolJoinVO.java @@ -25,13 +25,14 @@ import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; import com.cloud.org.Cluster; +import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.utils.db.GenericDao; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; -import org.apache.cloudstack.engine.subsystem.api.storage.ScopeType; + /** * Storage Pool DB view. @@ -125,7 +126,7 @@ public class StoragePoolJoinVO extends BaseViewVO implements InternalIdentity, I @Column(name="job_status") private int jobStatus; - + @Column(name = "scope") @Enumerated(value = EnumType.STRING) private ScopeType scope; diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index e9b0c827ab7..27df1affb20 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -41,20 +41,17 @@ import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd; import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; +import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; 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.PrimaryDataStoreInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.region.RegionVO; import org.apache.cloudstack.region.dao.RegionDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -118,7 +115,7 @@ import com.cloud.org.Grouping.AllocationState; import com.cloud.org.Managed; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.GuestOSCategoryVO; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.S3VO; import com.cloud.storage.ScopeType; @@ -167,94 +164,95 @@ import com.cloud.vm.dao.VMInstanceDao; @Component @Local({ ResourceManager.class, ResourceService.class }) -public class ResourceManagerImpl extends ManagerBase implements ResourceManager, ResourceService, - Manager { - private static final Logger s_logger = Logger - .getLogger(ResourceManagerImpl.class); +public class ResourceManagerImpl extends ManagerBase implements ResourceManager, ResourceService, Manager { + private static final Logger s_logger = Logger.getLogger(ResourceManagerImpl.class); @Inject - AccountManager _accountMgr; + AccountManager _accountMgr; @Inject - AgentManager _agentMgr; + AgentManager _agentMgr; @Inject - StorageManager _storageMgr; + StorageManager _storageMgr; @Inject - protected SecondaryStorageVmManager _secondaryStorageMgr; + protected SecondaryStorageVmManager _secondaryStorageMgr; @Inject - DataStoreProviderManager _dataStoreProviderMgr; + DataStoreProviderManager _dataStoreProviderMgr; @Inject - protected RegionDao _regionDao; + protected RegionDao _regionDao; @Inject - protected DataCenterDao _dcDao; + protected DataCenterDao _dcDao; @Inject - protected HostPodDao _podDao; + protected HostPodDao _podDao; @Inject - protected ClusterDetailsDao _clusterDetailsDao; + protected ClusterDetailsDao _clusterDetailsDao; @Inject - protected ClusterDao _clusterDao; + protected ClusterDao _clusterDao; @Inject - protected CapacityDao _capacityDao; + protected CapacityDao _capacityDao; @Inject - protected HostDao _hostDao; + protected HostDao _hostDao; @Inject protected SwiftManager _swiftMgr; @Inject - protected S3Manager _s3Mgr; + protected S3Manager _s3Mgr; @Inject - protected HostDetailsDao _hostDetailsDao; + protected HostDetailsDao _hostDetailsDao; @Inject protected ConfigurationDao _configDao; @Inject - protected HostTagsDao _hostTagsDao; + protected HostTagsDao _hostTagsDao; @Inject - protected GuestOSCategoryDao _guestOSCategoryDao; + protected GuestOSCategoryDao _guestOSCategoryDao; @Inject - protected PrimaryDataStoreDao _storagePoolDao; + protected PrimaryDataStoreDao _storagePoolDao; @Inject - protected DataCenterIpAddressDao _privateIPAddressDao; + protected DataCenterIpAddressDao _privateIPAddressDao; @Inject - protected IPAddressDao _publicIPAddressDao; + protected IPAddressDao _publicIPAddressDao; @Inject - protected VirtualMachineManager _vmMgr; + protected VirtualMachineManager _vmMgr; @Inject - protected VMInstanceDao _vmDao; + protected VMInstanceDao _vmDao; @Inject - protected HighAvailabilityManager _haMgr; + protected HighAvailabilityManager _haMgr; @Inject - protected StorageService _storageSvr; + protected StorageService _storageSvr; @Inject DataStoreManager _dataStoreMgr; - protected List _discoverers; + public List getDiscoverers() { - return _discoverers; - } - public void setDiscoverers(List _discoverers) { - this._discoverers = _discoverers; - } + return _discoverers; + } + + public void setDiscoverers(List _discoverers) { + this._discoverers = _discoverers; + } - @Inject - protected ClusterManager _clusterMgr; @Inject - protected StoragePoolHostDao _storagePoolHostDao; + protected ClusterManager _clusterMgr; + @Inject + protected StoragePoolHostDao _storagePoolHostDao; + + protected List _podAllocators; - protected List _podAllocators; public List getPodAllocators() { - return _podAllocators; - } - public void setPodAllocators(List _podAllocators) { - this._podAllocators = _podAllocators; - } + return _podAllocators; + } - @Inject - protected VMTemplateDao _templateDao; - @Inject - protected ConfigurationManager _configMgr; - @Inject - protected ClusterVSMMapDao _clusterVSMMapDao; + public void setPodAllocators(List _podAllocators) { + this._podAllocators = _podAllocators; + } - protected long _nodeId = ManagementServerNode.getManagementServerId(); + @Inject + protected VMTemplateDao _templateDao; + @Inject + protected ConfigurationManager _configMgr; + @Inject + protected ClusterVSMMapDao _clusterVSMMapDao; + + protected long _nodeId = ManagementServerNode.getManagementServerId(); protected HashMap _resourceStateAdapters = new HashMap(); @@ -271,8 +269,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } if (lst.contains(listener)) { - throw new CloudRuntimeException("Duplicate resource lisener:" - + listener.getClass().getSimpleName()); + throw new CloudRuntimeException("Duplicate resource lisener:" + listener.getClass().getSimpleName()); } lst.add(listener); @@ -288,31 +285,22 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, insertListener(ResourceListener.EVENT_DISCOVER_AFTER, listener); } if ((event & ResourceListener.EVENT_DELETE_HOST_BEFORE) != 0) { - insertListener(ResourceListener.EVENT_DELETE_HOST_BEFORE, - listener); + insertListener(ResourceListener.EVENT_DELETE_HOST_BEFORE, listener); } if ((event & ResourceListener.EVENT_DELETE_HOST_AFTER) != 0) { - insertListener(ResourceListener.EVENT_DELETE_HOST_AFTER, - listener); + insertListener(ResourceListener.EVENT_DELETE_HOST_AFTER, listener); } if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE) != 0) { - insertListener( - ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, - listener); + insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, listener); } if ((event & ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER) != 0) { - insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, - listener); + insertListener(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, listener); } if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE) != 0) { - insertListener( - ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, - listener); + insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, listener); } if ((event & ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER) != 0) { - insertListener( - ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, - listener); + insertListener(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, listener); } } } @@ -322,15 +310,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, synchronized (_lifeCycleListeners) { Iterator it = _lifeCycleListeners.entrySet().iterator(); while (it.hasNext()) { - Map.Entry> items = (Map.Entry>) it - .next(); + Map.Entry> items = (Map.Entry>) it.next(); List lst = items.getValue(); lst.remove(listener); } } } - protected void processResourceEvent(Integer event, Object... params) { + protected void processResourceEvent(Integer event, Object... params) { List lst = _lifeCycleListeners.get(event); if (lst == null || lst.size() == 0) { return; @@ -339,10 +326,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, String eventName; for (ResourceListener l : lst) { if (event == ResourceListener.EVENT_DISCOVER_BEFORE) { - l.processDiscoverEventBefore((Long) params[0], - (Long) params[1], (Long) params[2], (URI) params[3], - (String) params[4], (String) params[5], - (List) params[6]); + l.processDiscoverEventBefore((Long) params[0], (Long) params[1], (Long) params[2], (URI) params[3], (String) params[4], + (String) params[5], (List) params[6]); eventName = "EVENT_DISCOVER_BEFORE"; } else if (event == ResourceListener.EVENT_DISCOVER_AFTER) { l.processDiscoverEventAfter((Map>) params[0]); @@ -366,20 +351,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, l.processPrepareMaintenaceEventAfter((Long) params[0]); eventName = "EVENT_PREPARE_MAINTENANCE_AFTER"; } else { - throw new CloudRuntimeException("Unknown resource event:" - + event); + throw new CloudRuntimeException("Unknown resource event:" + event); } - s_logger.debug("Sent resource event " + eventName + " to listener " - + l.getClass().getSimpleName()); + s_logger.debug("Sent resource event " + eventName + " to listener " + l.getClass().getSimpleName()); } } @DB @Override - public List discoverCluster(AddClusterCmd cmd) - throws IllegalArgumentException, DiscoveryException, - ResourceInUseException { + public List discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException { long dcId = cmd.getZoneId(); long podId = cmd.getPodId(); String clusterName = cmd.getClusterName(); @@ -396,36 +377,31 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Check if the zone exists in the system DataCenterVO zone = _dcDao.findById(dcId); if (zone == null) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "Can't find zone by the id specified"); + InvalidParameterValueException ex = new InvalidParameterValueException("Can't find zone by the id specified"); ex.addProxyObject(zone, dcId, "dcId"); throw ex; } Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() - && !_accountMgr.isRootAdmin(account.getType())) { - PermissionDeniedException ex = new PermissionDeniedException( - "Cannot perform this operation, Zone with specified id is currently disabled"); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + PermissionDeniedException ex = new PermissionDeniedException( + "Cannot perform this operation, Zone with specified id is currently disabled"); ex.addProxyObject(zone, dcId, "dcId"); throw ex; } HostPodVO pod = _podDao.findById(podId); if (pod == null) { - throw new InvalidParameterValueException( - "Can't find pod with specified podId " + podId); + throw new InvalidParameterValueException("Can't find pod with specified podId " + podId); } // Check if the pod exists in the system if (_podDao.findById(podId) == null) { - throw new InvalidParameterValueException("Can't find pod by id " - + podId); + throw new InvalidParameterValueException("Can't find pod by id " + podId); } // check if pod belongs to the zone if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "Pod with specified id doesn't belong to the zone " + dcId); + InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified id doesn't belong to the zone " + dcId); ex.addProxyObject(pod, podId, "podId"); ex.addProxyObject(zone, dcId, "dcId"); throw ex; @@ -433,22 +409,17 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Verify cluster information and create a new cluster if needed if (clusterName == null || clusterName.isEmpty()) { - throw new InvalidParameterValueException( - "Please specify cluster name"); + throw new InvalidParameterValueException("Please specify cluster name"); } if (cmd.getHypervisor() == null || cmd.getHypervisor().isEmpty()) { - throw new InvalidParameterValueException( - "Please specify a hypervisor"); + throw new InvalidParameterValueException("Please specify a hypervisor"); } - Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType - .getType(cmd.getHypervisor()); + Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(cmd.getHypervisor()); if (hypervisorType == null) { - s_logger.error("Unable to resolve " + cmd.getHypervisor() - + " to a valid supported hypervisor type"); - throw new InvalidParameterValueException("Unable to resolve " - + cmd.getHypervisor() + " to a supported "); + s_logger.error("Unable to resolve " + cmd.getHypervisor() + " to a valid supported hypervisor type"); + throw new InvalidParameterValueException("Unable to resolve " + cmd.getHypervisor() + " to a supported "); } Cluster.ClusterType clusterType = null; @@ -460,16 +431,11 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } Grouping.AllocationState allocationState = null; - if (cmd.getAllocationState() != null - && !cmd.getAllocationState().isEmpty()) { + if (cmd.getAllocationState() != null && !cmd.getAllocationState().isEmpty()) { try { - allocationState = Grouping.AllocationState.valueOf(cmd - .getAllocationState()); + allocationState = Grouping.AllocationState.valueOf(cmd.getAllocationState()); } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException( - "Unable to resolve Allocation State '" - + cmd.getAllocationState() - + "' to a supported state"); + throw new InvalidParameterValueException("Unable to resolve Allocation State '" + cmd.getAllocationState() + "' to a supported state"); } } if (allocationState == null) { @@ -479,9 +445,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, Discoverer discoverer = getMatchingDiscover(hypervisorType); if (discoverer == null) { - throw new InvalidParameterValueException( - "Could not find corresponding resource manager for " - + cmd.getHypervisor()); + throw new InvalidParameterValueException("Could not find corresponding resource manager for " + cmd.getHypervisor()); } if (hypervisorType == HypervisorType.VMware) { @@ -501,9 +465,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, cluster = _clusterDao.persist(cluster); } catch (Exception e) { // no longer tolerate exception during the cluster creation phase - CloudRuntimeException ex = new CloudRuntimeException( - "Unable to create cluster " + clusterName - + " in pod and data center with specified ids", e); + CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + + " in pod and data center with specified ids", e); // Get the pod VO object's table name. ex.addProxyObject(pod, podId, "podId"); ex.addProxyObject(zone, dcId, "dcId"); @@ -512,10 +475,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, clusterId = cluster.getId(); result.add(cluster); - ClusterDetailsVO cluster_detail_cpu = new ClusterDetailsVO(clusterId, "cpuOvercommitRatio", Float.toString(cmd.getCpuOvercommitRatio())); - ClusterDetailsVO cluster_detail_ram = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", Float.toString(cmd.getMemoryOvercommitRaito())); - _clusterDetailsDao.persist(cluster_detail_cpu); - _clusterDetailsDao.persist(cluster_detail_ram); + ClusterDetailsVO cluster_detail_cpu = new ClusterDetailsVO(clusterId, "cpuOvercommitRatio", Float.toString(cmd.getCpuOvercommitRatio())); + ClusterDetailsVO cluster_detail_ram = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", Float.toString(cmd.getMemoryOvercommitRaito())); + _clusterDetailsDao.persist(cluster_detail_cpu); + _clusterDetailsDao.persist(cluster_detail_ram); if (clusterType == Cluster.ClusterType.CloudManaged) { return result; @@ -530,66 +493,53 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, _clusterDetailsDao.persist(cluster_detail_cpu); _clusterDetailsDao.persist(cluster_detail_ram); - //create a new entry only if the overcommit ratios are greater than 1. - if(cmd.getCpuOvercommitRatio().compareTo(1f) > 0) { + // create a new entry only if the overcommit ratios are greater than 1. + if (cmd.getCpuOvercommitRatio().compareTo(1f) > 0) { cluster_detail_cpu = new ClusterDetailsVO(clusterId, "cpuOvercommitRatio", Float.toString(cmd.getCpuOvercommitRatio())); _clusterDetailsDao.persist(cluster_detail_cpu); } - - if(cmd.getMemoryOvercommitRaito().compareTo(1f) > 0) { - cluster_detail_ram = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", Float.toString(cmd.getMemoryOvercommitRaito())); + if (cmd.getMemoryOvercommitRaito().compareTo(1f) > 0) { + cluster_detail_ram = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", Float.toString(cmd.getMemoryOvercommitRaito())); _clusterDetailsDao.persist(cluster_detail_ram); } - boolean success = false; try { try { uri = new URI(UriUtils.encodeURIComponent(url)); if (uri.getScheme() == null) { - throw new InvalidParameterValueException( - "uri.scheme is null " + url - + ", add http:// as a prefix"); + throw new InvalidParameterValueException("uri.scheme is null " + url + ", add http:// as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("http")) { - if (uri.getHost() == null - || uri.getHost().equalsIgnoreCase("") - || uri.getPath() == null - || uri.getPath().equalsIgnoreCase("")) { - throw new InvalidParameterValueException( - "Your host and/or path is wrong. Make sure it's of the format http://hostname/path"); + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { + throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format http://hostname/path"); } } } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url - + " is not a valid uri"); + throw new InvalidParameterValueException(url + " is not a valid uri"); } List hosts = new ArrayList(); Map> resources = null; - resources = discoverer.find(dcId, podId, clusterId, uri, username, - password, null); + resources = discoverer.find(dcId, podId, clusterId, uri, username, password, null); if (resources != null) { - for (Map.Entry> entry : resources - .entrySet()) { + for (Map.Entry> entry : resources.entrySet()) { ServerResource resource = entry.getKey(); - // For Hyper-V, we are here means agent have already started - // and connected to management server + // For Hyper-V, we are here means agent have already started + // and connected to management server if (hypervisorType == Hypervisor.HypervisorType.Hyperv) { break; } - HostVO host = (HostVO) createHostAndAgent(resource, - entry.getValue(), true, null, false); + HostVO host = (HostVO) createHostAndAgent(resource, entry.getValue(), true, null, false); if (host != null) { hosts.add(host); } discoverer.postDiscovery(hosts, _nodeId); } - s_logger.info("External cluster has been successfully discovered by " - + discoverer.getName()); + s_logger.info("External cluster has been successfully discovered by " + discoverer.getName()); success = true; return result; } @@ -605,19 +555,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public Discoverer getMatchingDiscover( - Hypervisor.HypervisorType hypervisorType) { - for (Discoverer discoverer : _discoverers) { - if (discoverer.getHypervisorType() == hypervisorType) + public Discoverer getMatchingDiscover(Hypervisor.HypervisorType hypervisorType) { + for (Discoverer discoverer : _discoverers) { + if (discoverer.getHypervisorType() == hypervisorType) return discoverer; - } + } return null; } @Override - public List discoverHosts(AddHostCmd cmd) - throws IllegalArgumentException, DiscoveryException, - InvalidParameterValueException { + public List discoverHosts(AddHostCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { Long dcId = cmd.getZoneId(); Long podId = cmd.getPodId(); Long clusterId = cmd.getClusterId(); @@ -627,8 +574,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, String password = cmd.getPassword(); List hostTags = cmd.getHostTags(); - dcId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current() - .getCaller(), dcId); + dcId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), dcId); // this is for standalone option if (clusterName == null && clusterId == null) { @@ -638,16 +584,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (clusterId != null) { ClusterVO cluster = _clusterDao.findById(clusterId); if (cluster == null) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "can not find cluster for specified clusterId"); + InvalidParameterValueException ex = new InvalidParameterValueException("can not find cluster for specified clusterId"); ex.addProxyObject(cluster, clusterId, "clusterId"); throw ex; } else { if (cluster.getGuid() == null) { List hosts = listAllHostsInCluster(clusterId); if (!hosts.isEmpty()) { - CloudRuntimeException ex = new CloudRuntimeException( - "Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up"); + CloudRuntimeException ex = new CloudRuntimeException( + "Guid is not updated for cluster with specified cluster id; need to wait for hosts in this cluster to come up"); ex.addProxyObject(cluster, clusterId, "clusterId"); throw ex; } @@ -655,17 +600,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } } - return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), true); + return discoverHostsFull(dcId, podId, clusterId, clusterName, url, username, password, cmd.getHypervisor(), hostTags, cmd.getFullUrlParams(), + true); } - - - - @Override - public List discoverHosts(AddSecondaryStorageCmd cmd) - throws IllegalArgumentException, DiscoveryException, - InvalidParameterValueException { + public List discoverHosts(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, + InvalidParameterValueException { Long dcId = cmd.getZoneId(); String url = cmd.getUrl(); return discoverHostsFull(dcId, null, null, null, url, null, null, "SecondaryStorage", null, null, false); @@ -678,7 +619,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public Pair, Integer> listSwifts(ListSwiftsCmd cmd) { - Pair, Integer> swifts = _swiftMgr.listSwifts(cmd); + Pair, Integer> swifts = _swiftMgr.listSwifts(cmd); return new Pair, Integer>(swifts.first(), swifts.second()); } @@ -693,53 +634,44 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public ObjectStore discoverObjectStore(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, + public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { - String providerName = cmd.getImageProviderName(); + String providerName = cmd.getProviderName(); DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); if (storeProvider == null) { storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider(); if (storeProvider == null) { - throw new InvalidParameterValueException( - "can't find image store provider: " + providerName); + throw new InvalidParameterValueException("can't find image store provider: " + providerName); } } Long dcId = cmd.getZoneId(); - Long regionId = cmd.getRegionId(); String url = cmd.getUrl(); Map details = cmd.getDetails(); - ScopeType scopeType = ScopeType.ZONE; + ScopeType scopeType = null; String scope = cmd.getScope(); if (scope != null) { try { scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); } catch (Exception e) { - throw new InvalidParameterValueException("invalid scope" - + scope); + throw new InvalidParameterValueException("invalid scope" + scope); } } if (scopeType == ScopeType.ZONE && dcId == null) { - throw new InvalidParameterValueException( - "zone id can't be null, if scope is zone"); - } else if (scopeType == ScopeType.REGION && regionId == null) { - throw new InvalidParameterValueException( - "region id can't be null, if scope is region"); + throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); } - if ( dcId != null ){ + if (dcId != null) { // Check if the zone exists in the system DataCenterVO zone = _dcDao.findById(dcId); if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " - + dcId); + throw new InvalidParameterValueException("Can't find zone by id " + dcId); } Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() - && !_accountMgr.isRootAdmin(account.getType())) { + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { PermissionDeniedException ex = new PermissionDeniedException( "Cannot perform this operation, Zone with specified id is currently disabled"); ex.addProxyObject(zone, dcId, "dcId"); @@ -747,57 +679,42 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } } - if ( regionId != null ){ - // Check if the region exists in the system - RegionVO region = _regionDao.findById(regionId.intValue()); - if (region == null) { - throw new InvalidParameterValueException("Can't find region by id " - + regionId); - } - } Map params = new HashMap(); params.put("zoneId", dcId); - params.put("regionId", regionId); params.put("url", cmd.getUrl()); params.put("name", cmd.getUrl()); params.put("details", details); + params.put("scope", scopeType); params.put("providerName", storeProvider.getName()); DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); DataStore store = null; try { store = lifeCycle.initialize(params); - - if (scopeType == ScopeType.ZONE) { - ZoneScope zoneScope = new ZoneScope(dcId); - lifeCycle.attachZone(store, zoneScope); - } } catch (Exception e) { s_logger.debug("Failed to add data store", e); throw new CloudRuntimeException("Failed to add data store", e); } - return (ObjectStore)_dataStoreMgr.getDataStore(store.getId(), - DataStoreRole.Image); + return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); } - private List discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List hostTags, - Map params, boolean deferAgentCreation) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { + private List discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, + String hypervisorType, List hostTags, Map params, boolean deferAgentCreation) throws IllegalArgumentException, + DiscoveryException, InvalidParameterValueException { URI uri = null; // Check if the zone exists in the system DataCenterVO zone = _dcDao.findById(dcId); if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " - + dcId); + throw new InvalidParameterValueException("Can't find zone by id " + dcId); } Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() - && !_accountMgr.isRootAdmin(account.getType())) { - PermissionDeniedException ex = new PermissionDeniedException( - "Cannot perform this operation, Zone with specified id is currently disabled"); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + PermissionDeniedException ex = new PermissionDeniedException( + "Cannot perform this operation, Zone with specified id is currently disabled"); ex.addProxyObject(zone, dcId, "dcId"); throw ex; } @@ -806,16 +723,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (podId != null) { HostPodVO pod = _podDao.findById(podId); if (pod == null) { - throw new InvalidParameterValueException( - "Can't find pod by id " + podId); + throw new InvalidParameterValueException("Can't find pod by id " + podId); } // check if pod belongs to the zone if (!Long.valueOf(pod.getDataCenterId()).equals(dcId)) { - InvalidParameterValueException ex = new InvalidParameterValueException( - "Pod with specified podId" - + podId - + " doesn't belong to the zone with specified zoneId" - + dcId); + InvalidParameterValueException ex = new InvalidParameterValueException("Pod with specified podId" + podId + + " doesn't belong to the zone with specified zoneId" + dcId); ex.addProxyObject(pod, podId, "podId"); ex.addProxyObject(zone, dcId, "dcId"); throw ex; @@ -824,47 +737,40 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Verify cluster information and create a new cluster if needed if (clusterName != null && clusterId != null) { - throw new InvalidParameterValueException( - "Can't specify cluster by both id and name"); + throw new InvalidParameterValueException("Can't specify cluster by both id and name"); } if (hypervisorType == null || hypervisorType.isEmpty()) { - throw new InvalidParameterValueException( - "Need to specify Hypervisor Type"); + throw new InvalidParameterValueException("Need to specify Hypervisor Type"); } if ((clusterName != null || clusterId != null) && podId == null) { - throw new InvalidParameterValueException( - "Can't specify cluster without specifying the pod"); + throw new InvalidParameterValueException("Can't specify cluster without specifying the pod"); } if (clusterId != null) { if (_clusterDao.findById(clusterId) == null) { - throw new InvalidParameterValueException( - "Can't find cluster by id " + clusterId); - } + throw new InvalidParameterValueException("Can't find cluster by id " + clusterId); + } - if (hypervisorType.equalsIgnoreCase(HypervisorType.VMware - .toString())) { - // VMware only allows adding host to an existing cluster, as we - // already have a lot of information - // in cluster object, to simplify user input, we will construct - // neccessary information here - Map clusterDetails = this._clusterDetailsDao - .findDetails(clusterId); + if (hypervisorType.equalsIgnoreCase(HypervisorType.VMware.toString())) { + // VMware only allows adding host to an existing cluster, as we + // already have a lot of information + // in cluster object, to simplify user input, we will construct + // neccessary information here + Map clusterDetails = this._clusterDetailsDao.findDetails(clusterId); username = clusterDetails.get("username"); - assert (username != null); + assert (username != null); password = clusterDetails.get("password"); - assert (password != null); + assert (password != null); try { uri = new URI(UriUtils.encodeURIComponent(url)); url = clusterDetails.get("url") + "/" + uri.getHost(); } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url - + " is not a valid uri"); + throw new InvalidParameterValueException(url + " is not a valid uri"); } } } @@ -872,8 +778,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (clusterName != null) { HostPodVO pod = _podDao.findById(podId); if (pod == null) { - throw new InvalidParameterValueException( - "Can't find pod by id " + podId); + throw new InvalidParameterValueException("Can't find pod by id " + podId); } ClusterVO cluster = new ClusterVO(dcId, podId, clusterName); cluster.setHypervisorType(hypervisorType); @@ -882,22 +787,19 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } catch (Exception e) { cluster = _clusterDao.findBy(clusterName, podId); if (cluster == null) { - CloudRuntimeException ex = new CloudRuntimeException( - "Unable to create cluster " - + clusterName - + " in pod with specified podId and data center with specified dcID", - e); + CloudRuntimeException ex = new CloudRuntimeException("Unable to create cluster " + clusterName + + " in pod with specified podId and data center with specified dcID", e); ex.addProxyObject(pod, podId, "podId"); ex.addProxyObject(zone, dcId, "dcId"); throw ex; } } clusterId = cluster.getId(); - if (_clusterDetailsDao.findDetail(clusterId,"cpuOvercommitRatio") == null) { - ClusterDetailsVO cluster_cpu_detail = new ClusterDetailsVO(clusterId,"cpuOvercommitRatio","1"); - ClusterDetailsVO cluster_memory_detail = new ClusterDetailsVO(clusterId,"memoryOvercommitRatio","1"); - _clusterDetailsDao.persist(cluster_cpu_detail); - _clusterDetailsDao.persist(cluster_memory_detail); + if (_clusterDetailsDao.findDetail(clusterId, "cpuOvercommitRatio") == null) { + ClusterDetailsVO cluster_cpu_detail = new ClusterDetailsVO(clusterId, "cpuOvercommitRatio", "1"); + ClusterDetailsVO cluster_memory_detail = new ClusterDetailsVO(clusterId, "memoryOvercommitRatio", "1"); + _clusterDetailsDao.persist(cluster_cpu_detail); + _clusterDetailsDao.persist(cluster_memory_detail); } } @@ -905,26 +807,20 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, try { uri = new URI(UriUtils.encodeURIComponent(url)); if (uri.getScheme() == null) { - throw new InvalidParameterValueException("uri.scheme is null " - + url + ", add nfs:// as a prefix"); + throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("nfs")) { - if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") - || uri.getPath() == null - || uri.getPath().equalsIgnoreCase("")) { - throw new InvalidParameterValueException( - "Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { + throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); } } } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url - + " is not a valid uri"); + throw new InvalidParameterValueException(url + " is not a valid uri"); } List hosts = new ArrayList(); - s_logger.info("Trying to add a new host at " + url + " in data center " - + dcId); + s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); boolean isHypervisorTypeSupported = false; - for (Discoverer discoverer : _discoverers) { + for (Discoverer discoverer : _discoverers) { if (params != null) { discoverer.putParam(params); } @@ -935,43 +831,35 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, isHypervisorTypeSupported = true; Map> resources = null; - processResourceEvent(ResourceListener.EVENT_DISCOVER_BEFORE, dcId, - podId, clusterId, uri, username, password, hostTags); + processResourceEvent(ResourceListener.EVENT_DISCOVER_BEFORE, dcId, podId, clusterId, uri, username, password, hostTags); try { - resources = discoverer.find(dcId, podId, clusterId, uri, - username, password, hostTags); - } catch (DiscoveryException e) { + resources = discoverer.find(dcId, podId, clusterId, uri, username, password, hostTags); + } catch (DiscoveryException e) { throw e; } catch (Exception e) { - s_logger.info("Exception in host discovery process with discoverer: " - + discoverer.getName() - + ", skip to another discoverer if there is any"); + s_logger.info("Exception in host discovery process with discoverer: " + discoverer.getName() + + ", skip to another discoverer if there is any"); } - processResourceEvent(ResourceListener.EVENT_DISCOVER_AFTER, - resources); + processResourceEvent(ResourceListener.EVENT_DISCOVER_AFTER, resources); if (resources != null) { - for (Map.Entry> entry : resources - .entrySet()) { + for (Map.Entry> entry : resources.entrySet()) { ServerResource resource = entry.getKey(); /* - * For KVM, if we go to here, that means kvm agent is - * already connected to mgt svr. + * For KVM, if we go to here, that means kvm agent is + * already connected to mgt svr. */ if (resource instanceof KvmDummyResourceBase) { Map details = entry.getValue(); String guid = details.get("guid"); - List kvmHosts = listAllUpAndEnabledHosts( - Host.Type.Routing, clusterId, podId, dcId); + List kvmHosts = listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId); for (HostVO host : kvmHosts) { if (host.getGuid().equalsIgnoreCase(guid)) { - if (hostTags != null) { - if (s_logger.isTraceEnabled()) { - s_logger.trace("Adding Host Tags for KVM host, tags: :" - + hostTags); + if (hostTags != null) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("Adding Host Tags for KVM host, tags: :" + hostTags); } - _hostTagsDao - .persist(host.getId(), hostTags); + _hostTagsDao.persist(host.getId(), hostTags); } hosts.add(host); return hosts; @@ -982,9 +870,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, HostVO host = null; if (deferAgentCreation) { - host = (HostVO)createHostAndAgentDeferred(resource, entry.getValue(), true, hostTags, false); + host = (HostVO) createHostAndAgentDeferred(resource, entry.getValue(), true, hostTags, false); } else { - host = (HostVO)createHostAndAgent(resource, entry.getValue(), true, hostTags, false); + host = (HostVO) createHostAndAgent(resource, entry.getValue(), true, hostTags, false); } if (host != null) { hosts.add(host); @@ -992,14 +880,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, discoverer.postDiscovery(hosts, _nodeId); } - s_logger.info("server resources successfully discovered by " - + discoverer.getName()); + s_logger.info("server resources successfully discovered by " + discoverer.getName()); return hosts; } } if (!isHypervisorTypeSupported) { - String msg = "Do not support HypervisorType " + hypervisorType - + " for " + url; + String msg = "Do not support HypervisorType " + hypervisorType + " for " + url; s_logger.warn(msg); throw new DiscoveryException(msg); } @@ -1013,42 +899,33 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @DB - protected boolean doDeleteHost(long hostId, boolean isForced, - boolean isForceDeleteStorage) { - User caller = _accountMgr.getActiveUser(UserContext.current() - .getCallerUserId()); + protected boolean doDeleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) { + User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); // Verify that host exists HostVO host = _hostDao.findById(hostId); if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId - + " doesn't exist"); + throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); } - _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current() - .getCaller(), host.getDataCenterId()); + _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), host.getDataCenterId()); /* - * TODO: check current agent status and updateAgentStatus to removed. If - * it was already removed, that means someone is deleting host - * concurrently, return. And consider the situation of CloudStack - * shutdown during delete. A global lock? + * TODO: check current agent status and updateAgentStatus to removed. If + * it was already removed, that means someone is deleting host + * concurrently, return. And consider the situation of CloudStack + * shutdown during delete. A global lock? */ AgentAttache attache = _agentMgr.findAttache(hostId); - // Get storage pool host mappings here because they can be removed as a - // part of handleDisconnect later - // TODO: find out the bad boy, what's a buggy logic! - List pools = _storagePoolHostDao - .listByHostIdIncludingRemoved(hostId); + // Get storage pool host mappings here because they can be removed as a + // part of handleDisconnect later + // TODO: find out the bad boy, what's a buggy logic! + List pools = _storagePoolHostDao.listByHostIdIncludingRemoved(hostId); - ResourceStateAdapter.DeleteHostAnswer answer = (ResourceStateAdapter.DeleteHostAnswer) dispatchToStateAdapters( - ResourceStateAdapter.Event.DELETE_HOST, false, host, - new Boolean(isForced), new Boolean(isForceDeleteStorage)); + ResourceStateAdapter.DeleteHostAnswer answer = (ResourceStateAdapter.DeleteHostAnswer) dispatchToStateAdapters( + ResourceStateAdapter.Event.DELETE_HOST, false, host, new Boolean(isForced), new Boolean(isForceDeleteStorage)); if (answer == null) { - throw new CloudRuntimeException( - "No resource adapter respond to DELETE_HOST event for " - + host.getName() + " id = " + hostId - + ", hypervisorType is " + host.getHypervisorType() - + ", host type is " + host.getType()); + throw new CloudRuntimeException("No resource adapter respond to DELETE_HOST event for " + host.getName() + " id = " + hostId + + ", hypervisorType is " + host.getHypervisorType() + ", host type is " + host.getType()); } if (answer.getIsException()) { @@ -1062,8 +939,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, Transaction txn = Transaction.currentTxn(); txn.start(); - _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), - host.getDataCenterId(), null); + _dcDao.releasePrivateIpAddress(host.getPrivateIpAddress(), host.getDataCenterId(), null); _agentMgr.disconnectWithoutInvestigation(hostId, Status.Event.Remove); // delete host details @@ -1085,18 +961,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } try { - resourceStateTransitTo(host, ResourceState.Event.DeleteHost, - _nodeId); + resourceStateTransitTo(host, ResourceState.Event.DeleteHost, _nodeId); } catch (NoTransitionException e) { - s_logger.debug("Cannot transmit host " + host.getId() - + "to Enabled state", e); + s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e); } // Delete the associated entries in host ref table _storagePoolHostDao.deletePrimaryRecordsForHost(hostId); - // For pool ids you got, delete local storage host entries in pool table - // where + // For pool ids you got, delete local storage host entries in pool table + // where for (StoragePoolHostVO pool : pools) { Long poolId = pool.getPoolId(); StoragePoolVO storagePool = _storagePoolDao.findById(poolId); @@ -1105,30 +979,24 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, storagePool.setClusterId(null); _storagePoolDao.update(poolId, storagePool); _storagePoolDao.remove(poolId); - s_logger.debug("Local storage id=" + poolId - + " is removed as a part of host removal id=" + hostId); + s_logger.debug("Local storage id=" + poolId + " is removed as a part of host removal id=" + hostId); } } // delete the op_host_capacity entry - Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU, - Capacity.CAPACITY_TYPE_MEMORY }; - SearchCriteria hostCapacitySC = _capacityDao - .createSearchCriteria(); + Object[] capacityTypes = { Capacity.CAPACITY_TYPE_CPU, Capacity.CAPACITY_TYPE_MEMORY }; + SearchCriteria hostCapacitySC = _capacityDao.createSearchCriteria(); hostCapacitySC.addAnd("hostOrPoolId", SearchCriteria.Op.EQ, hostId); - hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, - capacityTypes); + hostCapacitySC.addAnd("capacityType", SearchCriteria.Op.IN, capacityTypes); _capacityDao.remove(hostCapacitySC); txn.commit(); return true; } @Override - public boolean deleteHost(long hostId, boolean isForced, - boolean isForceDeleteStorage) { + public boolean deleteHost(long hostId, boolean isForced, boolean isForceDeleteStorage) { try { - Boolean result = _clusterMgr.propagateResourceEvent(hostId, - ResourceState.Event.DeleteHost); + Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.DeleteHost); if (result != null) { return result; } @@ -1148,58 +1016,47 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, ClusterVO cluster = _clusterDao.lockRow(cmd.getId(), true); if (cluster == null) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() - + " does not even exist. Delete call is ignored."); + s_logger.debug("Cluster: " + cmd.getId() + " does not even exist. Delete call is ignored."); } txn.rollback(); - throw new CloudRuntimeException("Cluster: " + cmd.getId() - + " does not exist"); + throw new CloudRuntimeException("Cluster: " + cmd.getId() + " does not exist"); } - Hypervisor.HypervisorType hypervisorType = cluster - .getHypervisorType(); + Hypervisor.HypervisorType hypervisorType = cluster.getHypervisorType(); List hosts = listAllHostsInCluster(cmd.getId()); if (hosts.size() > 0) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() - + " still has hosts, can't remove"); + s_logger.debug("Cluster: " + cmd.getId() + " still has hosts, can't remove"); } txn.rollback(); - throw new CloudRuntimeException("Cluster: " + cmd.getId() - + " cannot be removed. Cluster still has hosts"); + throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has hosts"); } - // don't allow to remove the cluster if it has non-removed storage - // pools - List storagePools = _storagePoolDao - .listPoolsByCluster(cmd.getId()); + // don't allow to remove the cluster if it has non-removed storage + // pools + List storagePools = _storagePoolDao.listPoolsByCluster(cmd.getId()); if (storagePools.size() > 0) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Cluster: " + cmd.getId() - + " still has storage pools, can't remove"); + s_logger.debug("Cluster: " + cmd.getId() + " still has storage pools, can't remove"); } txn.rollback(); - throw new CloudRuntimeException("Cluster: " + cmd.getId() - + " cannot be removed. Cluster still has storage pools"); + throw new CloudRuntimeException("Cluster: " + cmd.getId() + " cannot be removed. Cluster still has storage pools"); } - if (_clusterDao.remove(cmd.getId())) { + if (_clusterDao.remove(cmd.getId())) { _capacityDao.removeBy(null, null, null, cluster.getId(), null); - // If this cluster is of type vmware, and if the nexus vswitch - // global parameter setting is turned + // If this cluster is of type vmware, and if the nexus vswitch + // global parameter setting is turned // on, remove the row in cluster_vsm_map for this cluster id. - if (hypervisorType == HypervisorType.VMware - && Boolean.parseBoolean(_configDao - .getValue(Config.VmwareUseNexusVSwitch - .toString()))) { + if (hypervisorType == HypervisorType.VMware && Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) { _clusterVSMMapDao.removeByClusterId(cmd.getId()); } } txn.commit(); return true; - } catch (CloudRuntimeException e) { + } catch (CloudRuntimeException e) { throw e; } catch (Throwable t) { s_logger.error("Unable to delete cluster: " + cmd.getId(), t); @@ -1210,21 +1067,18 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override @DB - public Cluster updateCluster(Cluster clusterToUpdate, String clusterType, - String hypervisor, String allocationState, String managedstate,Float memoryovercommitratio, Float cpuovercommitratio) { + public Cluster updateCluster(Cluster clusterToUpdate, String clusterType, String hypervisor, String allocationState, String managedstate, + Float memoryovercommitratio, Float cpuovercommitratio) { ClusterVO cluster = (ClusterVO) clusterToUpdate; // Verify cluster information and update the cluster if needed boolean doUpdate = false; if (hypervisor != null && !hypervisor.isEmpty()) { - Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType - .getType(hypervisor); + Hypervisor.HypervisorType hypervisorType = Hypervisor.HypervisorType.getType(hypervisor); if (hypervisorType == null) { - s_logger.error("Unable to resolve " + hypervisor - + " to a valid supported hypervisor type"); - throw new InvalidParameterValueException("Unable to resolve " - + hypervisor + " to a supported type"); + s_logger.error("Unable to resolve " + hypervisor + " to a valid supported hypervisor type"); + throw new InvalidParameterValueException("Unable to resolve " + hypervisor + " to a supported type"); } else { cluster.setHypervisorType(hypervisor); doUpdate = true; @@ -1236,14 +1090,11 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, try { newClusterType = Cluster.ClusterType.valueOf(clusterType); } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException("Unable to resolve " - + clusterType + " to a supported type"); + throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type"); } if (newClusterType == null) { - s_logger.error("Unable to resolve " + clusterType - + " to a valid supported cluster type"); - throw new InvalidParameterValueException("Unable to resolve " - + clusterType + " to a supported type"); + s_logger.error("Unable to resolve " + clusterType + " to a valid supported cluster type"); + throw new InvalidParameterValueException("Unable to resolve " + clusterType + " to a supported type"); } else { cluster.setClusterType(newClusterType); doUpdate = true; @@ -1253,21 +1104,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, Grouping.AllocationState newAllocationState = null; if (allocationState != null && !allocationState.isEmpty()) { try { - newAllocationState = Grouping.AllocationState - .valueOf(allocationState); + newAllocationState = Grouping.AllocationState.valueOf(allocationState); } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException( - "Unable to resolve Allocation State '" - + allocationState + "' to a supported state"); + throw new InvalidParameterValueException("Unable to resolve Allocation State '" + allocationState + "' to a supported state"); } if (newAllocationState == null) { - s_logger.error("Unable to resolve " + allocationState - + " to a valid supported allocation State"); - throw new InvalidParameterValueException("Unable to resolve " - + allocationState + " to a supported state"); + s_logger.error("Unable to resolve " + allocationState + " to a valid supported allocation State"); + throw new InvalidParameterValueException("Unable to resolve " + allocationState + " to a supported state"); } else { - _capacityDao.updateCapacityState(null, null, cluster.getId(), - null, allocationState); + _capacityDao.updateCapacityState(null, null, cluster.getId(), null, allocationState); cluster.setAllocationState(newAllocationState); doUpdate = true; } @@ -1279,46 +1124,38 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, try { newManagedState = Managed.ManagedState.valueOf(managedstate); } catch (IllegalArgumentException ex) { - throw new InvalidParameterValueException( - "Unable to resolve Managed State '" + managedstate - + "' to a supported state"); + throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state"); } if (newManagedState == null) { - s_logger.error("Unable to resolve Managed State '" - + managedstate + "' to a supported state"); - throw new InvalidParameterValueException( - "Unable to resolve Managed State '" + managedstate - + "' to a supported state"); + s_logger.error("Unable to resolve Managed State '" + managedstate + "' to a supported state"); + throw new InvalidParameterValueException("Unable to resolve Managed State '" + managedstate + "' to a supported state"); } else { doUpdate = true; } } - ClusterDetailsVO memory_detail = _clusterDetailsDao.findDetail(cluster.getId(),"memoryOvercommitRatio"); - if( memory_detail == null){ - if (memoryovercommitratio.compareTo(1f) > 0){ - memory_detail = new ClusterDetailsVO(cluster.getId(),"memoryOvercommitRatio",Float.toString(memoryovercommitratio)); - _clusterDetailsDao.persist(memory_detail); - } - } - else { - memory_detail.setValue(Float.toString(memoryovercommitratio)); - _clusterDetailsDao.update(memory_detail.getId(),memory_detail); - } + ClusterDetailsVO memory_detail = _clusterDetailsDao.findDetail(cluster.getId(), "memoryOvercommitRatio"); + if (memory_detail == null) { + if (memoryovercommitratio.compareTo(1f) > 0) { + memory_detail = new ClusterDetailsVO(cluster.getId(), "memoryOvercommitRatio", Float.toString(memoryovercommitratio)); + _clusterDetailsDao.persist(memory_detail); + } + } else { + memory_detail.setValue(Float.toString(memoryovercommitratio)); + _clusterDetailsDao.update(memory_detail.getId(), memory_detail); + } - ClusterDetailsVO cpu_detail = _clusterDetailsDao.findDetail(cluster.getId(),"cpuOvercommitRatio"); - if( cpu_detail == null){ - if (cpuovercommitratio.compareTo(1f) > 0){ - cpu_detail = new ClusterDetailsVO(cluster.getId(),"cpuOvercommitRatio",Float.toString(cpuovercommitratio)); + ClusterDetailsVO cpu_detail = _clusterDetailsDao.findDetail(cluster.getId(), "cpuOvercommitRatio"); + if (cpu_detail == null) { + if (cpuovercommitratio.compareTo(1f) > 0) { + cpu_detail = new ClusterDetailsVO(cluster.getId(), "cpuOvercommitRatio", Float.toString(cpuovercommitratio)); _clusterDetailsDao.persist(cpu_detail); } - } - else { + } else { cpu_detail.setValue(Float.toString(cpuovercommitratio)); - _clusterDetailsDao.update(cpu_detail.getId(),cpu_detail); + _clusterDetailsDao.update(cpu_detail.getId(), cpu_detail); } - if (doUpdate) { Transaction txn = Transaction.currentTxn(); try { @@ -1326,82 +1163,67 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, _clusterDao.update(cluster.getId(), cluster); txn.commit(); } catch (Exception e) { - s_logger.error( - "Unable to update cluster due to " + e.getMessage(), e); - throw new CloudRuntimeException( - "Failed to update cluster. Please contact Cloud Support."); + s_logger.error("Unable to update cluster due to " + e.getMessage(), e); + throw new CloudRuntimeException("Failed to update cluster. Please contact Cloud Support."); } } - if (newManagedState != null && !newManagedState.equals(oldManagedState)) { + if (newManagedState != null && !newManagedState.equals(oldManagedState)) { Transaction txn = Transaction.currentTxn(); - if (newManagedState.equals(Managed.ManagedState.Unmanaged)) { + if (newManagedState.equals(Managed.ManagedState.Unmanaged)) { boolean success = false; try { txn.start(); cluster.setManagedState(Managed.ManagedState.PrepareUnmanaged); _clusterDao.update(cluster.getId(), cluster); txn.commit(); - List hosts = listAllUpAndEnabledHosts( - Host.Type.Routing, cluster.getId(), - cluster.getPodId(), cluster.getDataCenterId()); - for (HostVO host : hosts) { - if (host.getType().equals(Host.Type.Routing) - && !host.getStatus().equals(Status.Down) - && !host.getStatus() - .equals(Status.Disconnected) - && !host.getStatus().equals(Status.Up) - && !host.getStatus().equals(Status.Alert)) { - String msg = "host " + host.getPrivateIpAddress() - + " should not be in " - + host.getStatus().toString() + " status"; - throw new CloudRuntimeException( - "PrepareUnmanaged Failed due to " + msg); + List hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId()); + for (HostVO host : hosts) { + if (host.getType().equals(Host.Type.Routing) && !host.getStatus().equals(Status.Down) + && !host.getStatus().equals(Status.Disconnected) && !host.getStatus().equals(Status.Up) + && !host.getStatus().equals(Status.Alert)) { + String msg = "host " + host.getPrivateIpAddress() + " should not be in " + host.getStatus().toString() + " status"; + throw new CloudRuntimeException("PrepareUnmanaged Failed due to " + msg); } } - for (HostVO host : hosts) { - if (host.getStatus().equals(Status.Up)) { + for (HostVO host : hosts) { + if (host.getStatus().equals(Status.Up)) { umanageHost(host.getId()); } } int retry = 40; boolean lsuccess = true; - for (int i = 0; i < retry; i++) { + for (int i = 0; i < retry; i++) { lsuccess = true; try { Thread.sleep(5 * 1000); } catch (Exception e) { } - hosts = listAllUpAndEnabledHosts(Host.Type.Routing, - cluster.getId(), cluster.getPodId(), - cluster.getDataCenterId()); - for (HostVO host : hosts) { - if (!host.getStatus().equals(Status.Down) - && !host.getStatus().equals( - Status.Disconnected) + hosts = listAllUpAndEnabledHosts(Host.Type.Routing, cluster.getId(), cluster.getPodId(), cluster.getDataCenterId()); + for (HostVO host : hosts) { + if (!host.getStatus().equals(Status.Down) && !host.getStatus().equals(Status.Disconnected) && !host.getStatus().equals(Status.Alert)) { lsuccess = false; break; } } - if (lsuccess == true) { + if (lsuccess == true) { success = true; break; } } - if (success == false) { - throw new CloudRuntimeException( - "PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later "); + if (success == false) { + throw new CloudRuntimeException( + "PrepareUnmanaged Failed due to some hosts are still in UP status after 5 Minutes, please try later "); } } finally { txn.start(); - cluster.setManagedState(success ? Managed.ManagedState.Unmanaged - : Managed.ManagedState.PrepareUnmanagedError); + cluster.setManagedState(success ? Managed.ManagedState.Unmanaged : Managed.ManagedState.PrepareUnmanagedError); _clusterDao.update(cluster.getId(), cluster); txn.commit(); } - } else if (newManagedState.equals(Managed.ManagedState.Managed)) { + } else if (newManagedState.equals(Managed.ManagedState.Managed)) { txn.start(); cluster.setManagedState(Managed.ManagedState.Managed); _clusterDao.update(cluster.getId(), cluster); @@ -1420,18 +1242,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // verify input parameters HostVO host = _hostDao.findById(hostId); if (host == null || host.getRemoved() != null) { - throw new InvalidParameterValueException("Host with id " - + hostId.toString() + " doesn't exist"); + throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist"); } - processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, - hostId); + processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_BEFORE, hostId); boolean success = cancelMaintenance(hostId); - processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, - hostId); + processResourceEvent(ResourceListener.EVENT_CANCEL_MAINTENANCE_AFTER, hostId); if (!success) { - throw new CloudRuntimeException( - "Internal error cancelling maintenance."); + throw new CloudRuntimeException("Internal error cancelling maintenance."); } return host; } @@ -1442,63 +1260,51 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, HostVO host = _hostDao.findById(hostId); if (host == null) { - throw new InvalidParameterValueException("Host with id " - + hostId.toString() + " doesn't exist"); + throw new InvalidParameterValueException("Host with id " + hostId.toString() + " doesn't exist"); } return (_agentMgr.reconnect(hostId) ? host : null); } @Override - public boolean resourceStateTransitTo(Host host, ResourceState.Event event, - long msId) throws NoTransitionException { + public boolean resourceStateTransitTo(Host host, ResourceState.Event event, long msId) throws NoTransitionException { ResourceState currentState = host.getResourceState(); ResourceState nextState = currentState.getNextState(event); if (nextState == null) { - throw new NoTransitionException( - "No next resource state found for current state =" - + currentState + " event =" + event); + throw new NoTransitionException("No next resource state found for current state =" + currentState + " event =" + event); } - // TO DO - Make it more granular and have better conversion into - // capacity type + // TO DO - Make it more granular and have better conversion into + // capacity type - if (host.getType() == Type.Routing && host.getClusterId() != null) { - AllocationState capacityState = _configMgr - .findClusterAllocationState(ApiDBUtils.findClusterById(host - .getClusterId())); - if (capacityState == AllocationState.Enabled - && nextState != ResourceState.Enabled) { + if (host.getType() == Type.Routing && host.getClusterId() != null) { + AllocationState capacityState = _configMgr.findClusterAllocationState(ApiDBUtils.findClusterById(host.getClusterId())); + if (capacityState == AllocationState.Enabled && nextState != ResourceState.Enabled) { capacityState = AllocationState.Disabled; } - _capacityDao.updateCapacityState(null, null, null, host.getId(), - capacityState.toString()); + _capacityDao.updateCapacityState(null, null, null, host.getId(), capacityState.toString()); } - return _hostDao.updateResourceState(currentState, event, nextState, - host); + return _hostDao.updateResourceState(currentState, event, nextState, host); } private boolean doMaintain(final long hostId) { HostVO host = _hostDao.findById(hostId); - MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, - new MaintainCommand()); + MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, new MaintainCommand()); if (answer == null || !answer.getResult()) { s_logger.warn("Unable to send MaintainCommand to host: " + hostId); } try { - resourceStateTransitTo(host, - ResourceState.Event.AdminAskMaintenace, _nodeId); + resourceStateTransitTo(host, ResourceState.Event.AdminAskMaintenace, _nodeId); } catch (NoTransitionException e) { - String err = "Cannot transimit resource state of host " - + host.getId() + " to " + ResourceState.Maintenance; + String err = "Cannot transimit resource state of host " + host.getId() + " to " + ResourceState.Maintenance; s_logger.debug(err, e); throw new CloudRuntimeException(err + e.getMessage()); } _agentMgr.pullAgentToMaintenance(hostId); - /* TODO: move below to listener */ + /* TODO: move below to listener */ if (host.getType() == Host.Type.Routing) { final List vms = _vmDao.listByHostId(hostId); @@ -1506,9 +1312,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return true; } - List hosts = listAllUpAndEnabledHosts(Host.Type.Routing, - host.getClusterId(), host.getPodId(), - host.getDataCenterId()); + List hosts = listAllUpAndEnabledHosts(Host.Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId()); for (final VMInstanceVO vm : vms) { if (hosts == null || hosts.isEmpty() || !answer.getMigrate()) { // for the last host in this cluster, stop all the VMs @@ -1524,8 +1328,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public boolean maintain(final long hostId) throws AgentUnavailableException { - Boolean result = _clusterMgr.propagateResourceEvent(hostId, - ResourceState.Event.AdminAskMaintenace); + Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace); if (result != null) { return result; } @@ -1540,39 +1343,29 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (host == null) { s_logger.debug("Unable to find host " + hostId); - throw new InvalidParameterValueException( - "Unable to find host with ID: " + hostId - + ". Please specify a valid host ID."); + throw new InvalidParameterValueException("Unable to find host with ID: " + hostId + ". Please specify a valid host ID."); } - if (_hostDao.countBy(host.getClusterId(), - ResourceState.PrepareForMaintenance, - ResourceState.ErrorInMaintenance) > 0) { - throw new InvalidParameterValueException( - "There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " - + host.getClusterId()); + if (_hostDao.countBy(host.getClusterId(), ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance) > 0) { + throw new InvalidParameterValueException("There are other servers in PrepareForMaintenance OR ErrorInMaintenance STATUS in cluster " + + host.getClusterId()); } if (_storageMgr.isLocalStorageActiveOnHost(host.getId())) { - throw new InvalidParameterValueException( - "There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage."); + throw new InvalidParameterValueException( + "There are active VMs using the host's local storage pool. Please stop all VMs on this host that use local storage."); } try { - processResourceEvent( - ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, hostId); + processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_BEFORE, hostId); if (maintain(hostId)) { - processResourceEvent( - ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, - hostId); + processResourceEvent(ResourceListener.EVENT_PREPARE_MAINTENANCE_AFTER, hostId); return _hostDao.findById(hostId); } else { - throw new CloudRuntimeException( - "Unable to prepare for maintenance host " + hostId); + throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId); } } catch (AgentUnavailableException e) { - throw new CloudRuntimeException( - "Unable to prepare for maintenance host " + hostId); + throw new CloudRuntimeException("Unable to prepare for maintenance host " + hostId); } } @@ -1584,18 +1377,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Verify that the host exists HostVO host = _hostDao.findById(hostId); if (host == null) { - throw new InvalidParameterValueException("Host with id " + hostId - + " doesn't exist"); + throw new InvalidParameterValueException("Host with id " + hostId + " doesn't exist"); } if (cmd.getAllocationState() != null) { - ResourceState.Event resourceEvent = ResourceState.Event.toEvent(cmd - .getAllocationState()); - if (resourceEvent != ResourceState.Event.Enable - && resourceEvent != ResourceState.Event.Disable) { - throw new CloudRuntimeException("Invalid allocation state:" - + cmd.getAllocationState() - + ", only Enable/Disable are allowed"); + ResourceState.Event resourceEvent = ResourceState.Event.toEvent(cmd.getAllocationState()); + if (resourceEvent != ResourceState.Event.Enable && resourceEvent != ResourceState.Event.Disable) { + throw new CloudRuntimeException("Invalid allocation state:" + cmd.getAllocationState() + ", only Enable/Disable are allowed"); } resourceStateTransitTo(host, resourceEvent, _nodeId); @@ -1605,22 +1393,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Verify that the guest OS Category exists if (guestOSCategoryId > 0) { if (_guestOSCategoryDao.findById(guestOSCategoryId) == null) { - throw new InvalidParameterValueException( - "Please specify a valid guest OS category."); + throw new InvalidParameterValueException("Please specify a valid guest OS category."); } } - GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao - .findById(guestOSCategoryId); - Map hostDetails = _hostDetailsDao - .findDetails(hostId); + GuestOSCategoryVO guestOSCategory = _guestOSCategoryDao.findById(guestOSCategoryId); + Map hostDetails = _hostDetailsDao.findDetails(hostId); - if (guestOSCategory != null - && !GuestOSCategoryVO.CATEGORY_NONE - .equalsIgnoreCase(guestOSCategory.getName())) { + if (guestOSCategory != null && !GuestOSCategoryVO.CATEGORY_NONE.equalsIgnoreCase(guestOSCategory.getName())) { // Save a new entry for guest.os.category.id - hostDetails.put("guest.os.category.id", - String.valueOf(guestOSCategory.getId())); + hostDetails.put("guest.os.category.id", String.valueOf(guestOSCategory.getId())); } else { // Delete any existing entry for guest.os.category.id hostDetails.remove("guest.os.category.id"); @@ -1630,8 +1412,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, List hostTags = cmd.getHostTags(); if (hostTags != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Updating Host Tags to :" + hostTags); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Updating Host Tags to :" + hostTags); } _hostTagsDao.persist(hostId, hostTags); } @@ -1651,16 +1433,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public boolean configure(String name, Map params) - throws ConfigurationException { - _defaultSystemVMHypervisor = HypervisorType.getType(_configDao - .getValue(Config.SystemVMDefaultHypervisor.toString())); + public boolean configure(String name, Map params) throws ConfigurationException { + _defaultSystemVMHypervisor = HypervisorType.getType(_configDao.getValue(Config.SystemVMDefaultHypervisor.toString())); return true; } @Override - public List getSupportedHypervisorTypes(long zoneId, - boolean forVirtualRouter, Long podId) { + public List getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId) { List hypervisorTypes = new ArrayList(); List clustersForZone = new ArrayList(); @@ -1672,8 +1451,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, for (ClusterVO cluster : clustersForZone) { HypervisorType hType = cluster.getHypervisorType(); - if (!forVirtualRouter - || (forVirtualRouter && hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm)) { + if (!forVirtualRouter || (forVirtualRouter && hType != HypervisorType.BareMetal && hType != HypervisorType.Ovm)) { hypervisorTypes.add(hType); } } @@ -1693,14 +1471,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return HypervisorType.None; } _dcDao.loadDetails(dc); - String defaultHypervisorInZone = dc - .getDetail("defaultSystemVMHypervisorType"); + String defaultHypervisorInZone = dc.getDetail("defaultSystemVMHypervisorType"); if (defaultHypervisorInZone != null) { defaultHyper = HypervisorType.getType(defaultHypervisorInZone); } - List systemTemplates = _templateDao - .listAllSystemVMTemplates(); + List systemTemplates = _templateDao.listAllSystemVMTemplates(); boolean isValid = false; for (VMTemplateVO template : systemTemplates) { if (template.getHypervisorType() == defaultHyper) { @@ -1710,8 +1486,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } if (isValid) { - List clusters = _clusterDao.listByDcHyType(zoneId, - defaultHyper.toString()); + List clusters = _clusterDao.listByDcHyType(zoneId, defaultHyper.toString()); if (clusters.size() <= 0) { isValid = false; } @@ -1728,8 +1503,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, public HypervisorType getAvailableHypervisor(long zoneId) { HypervisorType defaultHype = getDefaultHypervisor(zoneId); if (defaultHype == HypervisorType.None) { - List supportedHypes = getSupportedHypervisorTypes( - zoneId, false, null); + List supportedHypes = getSupportedHypervisorTypes(zoneId, false, null); if (supportedHypes.size() > 0) { defaultHype = supportedHypes.get(0); } @@ -1742,8 +1516,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public void registerResourceStateAdapter(String name, - ResourceStateAdapter adapter) { + public void registerResourceStateAdapter(String name, ResourceStateAdapter adapter) { if (_resourceStateAdapters.get(name) != null) { throw new CloudRuntimeException(name + " has registered"); } @@ -1760,51 +1533,40 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } } - private Object dispatchToStateAdapters(ResourceStateAdapter.Event event, - boolean singleTaker, Object... args) { + private Object dispatchToStateAdapters(ResourceStateAdapter.Event event, boolean singleTaker, Object... args) { synchronized (_resourceStateAdapters) { Iterator it = _resourceStateAdapters.entrySet().iterator(); Object result = null; while (it.hasNext()) { - Map.Entry item = (Map.Entry) it - .next(); + Map.Entry item = (Map.Entry) it.next(); ResourceStateAdapter adapter = item.getValue(); - String msg = new String("Dispatching resource state event " - + event + " to " + item.getKey()); + String msg = new String("Dispatching resource state event " + event + " to " + item.getKey()); s_logger.debug(msg); if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED) { - result = adapter.createHostVOForConnectedAgent( - (HostVO) args[0], (StartupCommand[]) args[1]); + result = adapter.createHostVOForConnectedAgent((HostVO) args[0], (StartupCommand[]) args[1]); if (result != null && singleTaker) { break; } } else if (event == ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT) { - result = adapter.createHostVOForDirectConnectAgent( - (HostVO) args[0], (StartupCommand[]) args[1], - (ServerResource) args[2], - (Map) args[3], - (List) args[4]); + result = adapter.createHostVOForDirectConnectAgent((HostVO) args[0], (StartupCommand[]) args[1], (ServerResource) args[2], + (Map) args[3], (List) args[4]); if (result != null && singleTaker) { break; } } else if (event == ResourceStateAdapter.Event.DELETE_HOST) { try { - result = adapter.deleteHost((HostVO) args[0], - (Boolean) args[1], (Boolean) args[2]); + result = adapter.deleteHost((HostVO) args[0], (Boolean) args[1], (Boolean) args[2]); if (result != null) { break; } } catch (UnableDeleteHostException e) { - s_logger.debug("Adapter " + adapter.getName() - + " says unable to delete host", e); - result = new ResourceStateAdapter.DeleteHostAnswer( - false, true); + s_logger.debug("Adapter " + adapter.getName() + " says unable to delete host", e); + result = new ResourceStateAdapter.DeleteHostAnswer(false, true); } } else { - throw new CloudRuntimeException( - "Unknown resource state event:" + event); + throw new CloudRuntimeException("Unknown resource state event:" + event); } } @@ -1813,9 +1575,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public void checkCIDR(HostPodVO pod, DataCenterVO dc, - String serverPrivateIP, String serverPrivateNetmask) - throws IllegalArgumentException { + public void checkCIDR(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask) throws IllegalArgumentException { if (serverPrivateIP == null) { return; } @@ -1826,36 +1586,27 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // If the server's private IP address is not in the same subnet as the // pod's CIDR, return false String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize); - String serverSubnet = NetUtils.getSubNet(serverPrivateIP, - serverPrivateNetmask); + String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask); if (!cidrSubnet.equals(serverSubnet)) { - s_logger.warn("The private ip address of the server (" - + serverPrivateIP - + ") is not compatible with the CIDR of pod: " - + pod.getName() + " and zone: " + dc.getName()); - throw new IllegalArgumentException( - "The private ip address of the server (" + serverPrivateIP - + ") is not compatible with the CIDR of pod: " - + pod.getName() + " and zone: " + dc.getName()); + s_logger.warn("The private ip address of the server (" + serverPrivateIP + ") is not compatible with the CIDR of pod: " + pod.getName() + + " and zone: " + dc.getName()); + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " + dc.getName()); } // If the server's private netmask is less inclusive than the pod's CIDR // netmask, return false - String cidrNetmask = NetUtils - .getCidrSubNet("255.255.255.255", cidrSize); + String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize); long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask); long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask); if (serverNetmaskNumeric > cidrNetmaskNumeric) { - throw new IllegalArgumentException( - "The private ip address of the server (" + serverPrivateIP - + ") is not compatible with the CIDR of pod: " - + pod.getName() + " and zone: " + dc.getName()); + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + + ") is not compatible with the CIDR of pod: " + pod.getName() + " and zone: " + dc.getName()); } } - private boolean checkCIDR(HostPodVO pod, String serverPrivateIP, - String serverPrivateNetmask) { + private boolean checkCIDR(HostPodVO pod, String serverPrivateIP, String serverPrivateNetmask) { if (serverPrivateIP == null) { return true; } @@ -1866,16 +1617,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // If the server's private IP address is not in the same subnet as the // pod's CIDR, return false String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSize); - String serverSubnet = NetUtils.getSubNet(serverPrivateIP, - serverPrivateNetmask); + String serverSubnet = NetUtils.getSubNet(serverPrivateIP, serverPrivateNetmask); if (!cidrSubnet.equals(serverSubnet)) { return false; } // If the server's private netmask is less inclusive than the pod's CIDR // netmask, return false - String cidrNetmask = NetUtils - .getCidrSubNet("255.255.255.255", cidrSize); + String cidrNetmask = NetUtils.getCidrSubNet("255.255.255.255", cidrSize); long cidrNetmaskNumeric = NetUtils.ip2Long(cidrNetmask); long serverNetmaskNumeric = NetUtils.ip2Long(serverPrivateNetmask); if (serverNetmaskNumeric > cidrNetmaskNumeric) { @@ -1884,9 +1633,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return true; } - protected HostVO createHostVO(StartupCommand[] cmds, - ServerResource resource, Map details, - List hostTags, ResourceStateAdapter.Event stateEvent) { + protected HostVO createHostVO(StartupCommand[] cmds, ServerResource resource, Map details, List hostTags, + ResourceStateAdapter.Event stateEvent) { StartupCommand startup = cmds[0]; HostVO host = findHostByGuid(startup.getGuid()); boolean isNew = false; @@ -1902,16 +1650,12 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, String pod = startup.getPod(); String cluster = startup.getCluster(); - if (pod != null && dataCenter != null - && pod.equalsIgnoreCase("default") - && dataCenter.equalsIgnoreCase("default")) { + if (pod != null && dataCenter != null && pod.equalsIgnoreCase("default") && dataCenter.equalsIgnoreCase("default")) { List pods = _podDao.listAllIncludingRemoved(); for (HostPodVO hpv : pods) { - if (checkCIDR(hpv, startup.getPrivateIpAddress(), - startup.getPrivateNetmask())) { + if (checkCIDR(hpv, startup.getPrivateIpAddress(), startup.getPrivateNetmask())) { pod = hpv.getName(); - dataCenter = _dcDao.findById(hpv.getDataCenterId()) - .getName(); + dataCenter = _dcDao.findById(hpv.getDataCenterId()).getName(); break; } } @@ -1927,9 +1671,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } } if (dc == null) { - throw new IllegalArgumentException("Host " - + startup.getPrivateIpAddress() - + " sent incorrect data center: " + dataCenter); + throw new IllegalArgumentException("Host " + startup.getPrivateIpAddress() + " sent incorrect data center: " + dataCenter); } dcId = dc.getId(); @@ -1991,11 +1733,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, host.setResource(resource.getClass().getName()); } - host = (HostVO) dispatchToStateAdapters(stateEvent, true, host, cmds, - resource, details, hostTags); + host = (HostVO) dispatchToStateAdapters(stateEvent, true, host, cmds, resource, details, hostTags); if (host == null) { - throw new CloudRuntimeException( - "No resource state adapter response"); + throw new CloudRuntimeException("No resource state adapter response"); } if (isNew) { @@ -2005,28 +1745,23 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } try { - resourceStateTransitTo(host, ResourceState.Event.InternalCreated, - _nodeId); + resourceStateTransitTo(host, ResourceState.Event.InternalCreated, _nodeId); /* Agent goes to Connecting status */ - _agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, - _nodeId); + _agentMgr.agentStatusTransitTo(host, Status.Event.AgentConnected, _nodeId); } catch (Exception e) { - s_logger.debug("Cannot transmit host " + host.getId() - + " to Creating state", e); + s_logger.debug("Cannot transmit host " + host.getId() + " to Creating state", e); _agentMgr.agentStatusTransitTo(host, Status.Event.Error, _nodeId); try { resourceStateTransitTo(host, ResourceState.Event.Error, _nodeId); } catch (NoTransitionException e1) { - s_logger.debug("Cannot transmit host " + host.getId() - + "to Error state", e); + s_logger.debug("Cannot transmit host " + host.getId() + "to Error state", e); } } return host; } - private boolean isFirstHostInCluster(HostVO host) - { + private boolean isFirstHostInCluster(HostVO host) { boolean isFirstHost = true; if (host.getClusterId() != null) { SearchBuilder sb = _hostDao.createSearchBuilder(); @@ -2045,7 +1780,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } private void markHostAsDisconnected(HostVO host, StartupCommand[] cmds) { - if (host == null) { // in case host is null due to some errors, try reloading the host from db + if (host == null) { // in case host is null due to some errors, try + // reloading the host from db if (cmds != null) { StartupCommand firstCmd = cmds[0]; host = findHostByGuid(firstCmd.getGuid()); @@ -2056,13 +1792,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } if (host != null) { - // Change agent status to Alert, so that host is considered for reconnection next time + // Change agent status to Alert, so that host is considered for + // reconnection next time _agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId); } } - private Host createHostAndAgent(ServerResource resource, Map details, boolean old, List hostTags, - boolean forRebalance) { + private Host createHostAndAgent(ServerResource resource, Map details, boolean old, List hostTags, boolean forRebalance) { HostVO host = null; AgentAttache attache = null; StartupCommand[] cmds = null; @@ -2076,17 +1812,16 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } /* Generate a random version in a dev setup situation */ - if (this.getClass().getPackage().getImplementationVersion() == null) { - for (StartupCommand cmd : cmds) { - if (cmd.getVersion() == null) { + if (this.getClass().getPackage().getImplementationVersion() == null) { + for (StartupCommand cmd : cmds) { + if (cmd.getVersion() == null) { cmd.setVersion(Long.toString(System.currentTimeMillis())); } } } if (s_logger.isDebugEnabled()) { - new Request(-1l, -1l, cmds, true, false).logD( - "Startup request from directly connected host: ", true); + new Request(-1l, -1l, cmds, true, false).logD("Startup request from directly connected host: ", true); } if (old) { @@ -2095,22 +1830,21 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (host == null) { host = findHostByGuid(firstCmd.getGuidWithoutResource()); } - if (host != null && host.getRemoved() == null) { // host already added, no need to add again + if (host != null && host.getRemoved() == null) { // host already + // added, no + // need to add + // again s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new"); - hostExists = true; // ensures that host status is left unchanged in case of adding same one again + hostExists = true; // ensures that host status is left + // unchanged in case of adding same one + // again return null; } } - host = createHostVO( - cmds, - resource, - details, - hostTags, - ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT); + host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT); if (host != null) { - attache = _agentMgr.handleDirectConnectAgent(host, cmds, - resource, forRebalance); + attache = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance); /* reload myself from database */ host = _hostDao.findById(host.getId()); } @@ -2150,9 +1884,9 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } /* Generate a random version in a dev setup situation */ - if ( this.getClass().getPackage().getImplementationVersion() == null ) { - for ( StartupCommand cmd : cmds ) { - if ( cmd.getVersion() == null ) { + if (this.getClass().getPackage().getImplementationVersion() == null) { + for (StartupCommand cmd : cmds) { + if (cmd.getVersion() == null) { cmd.setVersion(Long.toString(System.currentTimeMillis())); } } @@ -2168,9 +1902,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (host == null) { host = findHostByGuid(firstCmd.getGuidWithoutResource()); } - if (host != null && host.getRemoved() == null) { // host already added, no need to add again + if (host != null && host.getRemoved() == null) { // host already + // added, no + // need to add + // again s_logger.debug("Found the host " + host.getId() + " by guid: " + firstCmd.getGuid() + ", old host reconnected as new"); - hostExists = true; // ensures that host status is left unchanged in case of adding same one again + hostExists = true; // ensures that host status is left + // unchanged in case of adding same one + // again return null; } } @@ -2178,11 +1917,30 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, host = null; GlobalLock addHostLock = GlobalLock.getInternLock("AddHostLock"); try { - if (addHostLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { // to safely determine first host in cluster in multi-MS scenario + if (addHostLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) { // to + // safely + // determine + // first + // host + // in + // cluster + // in + // multi-MS + // scenario try { host = createHostVO(cmds, resource, details, hostTags, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_DIRECT_CONNECT); if (host != null) { - deferAgentCreation = !isFirstHostInCluster(host); // if first host in cluster no need to defer agent creation + deferAgentCreation = !isFirstHostInCluster(host); // if + // first + // host + // in + // cluster + // no + // need + // to + // defer + // agent + // creation } } finally { addHostLock.unlock(); @@ -2193,12 +1951,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } if (host != null) { - if (!deferAgentCreation) { // if first host in cluster then create agent otherwise defer it to scan task + if (!deferAgentCreation) { // if first host in cluster then + // create agent otherwise defer it to + // scan task attache = _agentMgr.handleDirectConnectAgent(host, cmds, resource, forRebalance); host = _hostDao.findById(host.getId()); // reload } else { host = _hostDao.findById(host.getId()); // reload - // force host status to 'Alert' so that it is loaded for connection during next scan task + // force host status to 'Alert' so that it is loaded for + // connection during next scan task _agentMgr.agentStatusTransitTo(host, Status.Event.AgentDisconnected, _nodeId); host = _hostDao.findById(host.getId()); // reload @@ -2207,7 +1968,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // schedule a scan task immediately if (_agentMgr instanceof ClusteredAgentManagerImpl) { - ClusteredAgentManagerImpl clusteredAgentMgr = (ClusteredAgentManagerImpl)_agentMgr; + ClusteredAgentManagerImpl clusteredAgentMgr = (ClusteredAgentManagerImpl) _agentMgr; if (s_logger.isDebugEnabled()) { s_logger.debug("Scheduling a host scan task"); } @@ -2242,29 +2003,24 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public Host createHostAndAgent(Long hostId, ServerResource resource, - Map details, boolean old, List hostTags, - boolean forRebalance) { + public Host createHostAndAgent(Long hostId, ServerResource resource, Map details, boolean old, List hostTags, + boolean forRebalance) { _agentMgr.tapLoadingAgents(hostId, TapAgentsAction.Add); - Host host = createHostAndAgent(resource, details, old, hostTags, - forRebalance); + Host host = createHostAndAgent(resource, details, old, hostTags, forRebalance); _agentMgr.tapLoadingAgents(hostId, TapAgentsAction.Del); return host; } @Override - public Host addHost(long zoneId, ServerResource resource, Type hostType, - Map hostDetails) { + public Host addHost(long zoneId, ServerResource resource, Type hostType, Map hostDetails) { // Check if the zone exists in the system if (_dcDao.findById(zoneId) == null) { - throw new InvalidParameterValueException("Can't find zone with id " - + zoneId); + throw new InvalidParameterValueException("Can't find zone with id " + zoneId); } Map details = hostDetails; String guid = details.get("guid"); - List currentHosts = this - .listAllUpAndEnabledHostsInOneZoneByType(hostType, zoneId); + List currentHosts = this.listAllUpAndEnabledHostsInOneZoneByType(hostType, zoneId); for (HostVO currentHost : currentHosts) { if (currentHost.getGuid().equals(guid)) { return currentHost; @@ -2276,85 +2032,59 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public HostVO createHostVOForConnectedAgent(StartupCommand[] cmds) { - return createHostVO(cmds, null, null, null, - ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED); + return createHostVO(cmds, null, null, null, ResourceStateAdapter.Event.CREATE_HOST_VO_FOR_CONNECTED); } - private void checkIPConflicts(HostPodVO pod, DataCenterVO dc, - String serverPrivateIP, String serverPrivateNetmask, - String serverPublicIP, String serverPublicNetmask) { + private void checkIPConflicts(HostPodVO pod, DataCenterVO dc, String serverPrivateIP, String serverPrivateNetmask, String serverPublicIP, + String serverPublicNetmask) { // If the server's private IP is the same as is public IP, this host has // a host-only private network. Don't check for conflicts with the // private IP address table. if (serverPrivateIP != serverPublicIP) { - if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), - serverPrivateIP)) { + if (!_privateIPAddressDao.mark(dc.getId(), pod.getId(), serverPrivateIP)) { // If the server's private IP address is already in the // database, return false - List existingPrivateIPs = _privateIPAddressDao - .listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), - serverPrivateIP); + List existingPrivateIPs = _privateIPAddressDao.listByPodIdDcIdIpAddress(pod.getId(), dc.getId(), + serverPrivateIP); - assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " - + serverPrivateIP; + assert existingPrivateIPs.size() <= 1 : " How can we get more than one ip address with " + serverPrivateIP; if (existingPrivateIPs.size() > 1) { - throw new IllegalArgumentException( - "The private ip address of the server (" - + serverPrivateIP - + ") is already in use in pod: " - + pod.getName() + " and zone: " - + dc.getName()); + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + ") is already in use in pod: " + + pod.getName() + " and zone: " + dc.getName()); } if (existingPrivateIPs.size() == 1) { DataCenterIpAddressVO vo = existingPrivateIPs.get(0); if (vo.getInstanceId() != null) { - throw new IllegalArgumentException( - "The private ip address of the server (" - + serverPrivateIP - + ") is already in use in pod: " - + pod.getName() + " and zone: " - + dc.getName()); + throw new IllegalArgumentException("The private ip address of the server (" + serverPrivateIP + + ") is already in use in pod: " + pod.getName() + " and zone: " + dc.getName()); } } } } - if (serverPublicIP != null - && !_publicIPAddressDao - .mark(dc.getId(), new Ip(serverPublicIP))) { + if (serverPublicIP != null && !_publicIPAddressDao.mark(dc.getId(), new Ip(serverPublicIP))) { // If the server's public IP address is already in the database, // return false - List existingPublicIPs = _publicIPAddressDao - .listByDcIdIpAddress(dc.getId(), serverPublicIP); + List existingPublicIPs = _publicIPAddressDao.listByDcIdIpAddress(dc.getId(), serverPublicIP); if (existingPublicIPs.size() > 0) { - throw new IllegalArgumentException( - "The public ip address of the server (" - + serverPublicIP - + ") is already in use in zone: " - + dc.getName()); + throw new IllegalArgumentException("The public ip address of the server (" + serverPublicIP + ") is already in use in zone: " + + dc.getName()); } } } @Override - public HostVO fillRoutingHostVO(HostVO host, StartupRoutingCommand ssCmd, - HypervisorType hyType, Map details, - List hostTags) { + public HostVO fillRoutingHostVO(HostVO host, StartupRoutingCommand ssCmd, HypervisorType hyType, Map details, + List hostTags) { if (host.getPodId() == null) { - s_logger.error("Host " + ssCmd.getPrivateIpAddress() - + " sent incorrect pod, pod id is null"); - throw new IllegalArgumentException("Host " - + ssCmd.getPrivateIpAddress() - + " sent incorrect pod, pod id is null"); + s_logger.error("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null"); + throw new IllegalArgumentException("Host " + ssCmd.getPrivateIpAddress() + " sent incorrect pod, pod id is null"); } ClusterVO clusterVO = _clusterDao.findById(host.getClusterId()); if (clusterVO.getHypervisorType() != hyType) { - throw new IllegalArgumentException( - "Can't add host whose hypervisor type is: " + hyType - + " into cluster: " + clusterVO.getId() - + " whose hypervisor type is: " - + clusterVO.getHypervisorType()); + throw new IllegalArgumentException("Can't add host whose hypervisor type is: " + hyType + " into cluster: " + clusterVO.getId() + + " whose hypervisor type is: " + clusterVO.getHypervisorType()); } final Map hostDetails = ssCmd.getHostDetails(); @@ -2368,9 +2098,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, HostPodVO pod = _podDao.findById(host.getPodId()); DataCenterVO dc = _dcDao.findById(host.getDataCenterId()); - checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), - ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), - ssCmd.getPublicNetmask()); + checkIPConflicts(pod, dc, ssCmd.getPrivateIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicIpAddress(), ssCmd.getPublicNetmask()); host.setType(com.cloud.host.Host.Type.Routing); host.setDetails(details); host.setCaps(ssCmd.getCapabilities()); @@ -2383,69 +2111,48 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public void deleteRoutingHost(HostVO host, boolean isForced, - boolean forceDestroyStorage) throws UnableDeleteHostException { + public void deleteRoutingHost(HostVO host, boolean isForced, boolean forceDestroyStorage) throws UnableDeleteHostException { if (host.getType() != Host.Type.Routing) { - throw new CloudRuntimeException( - "Non-Routing host gets in deleteRoutingHost, id is " - + host.getId()); + throw new CloudRuntimeException("Non-Routing host gets in deleteRoutingHost, id is " + host.getId()); } if (s_logger.isDebugEnabled()) { - s_logger.debug("Deleting Host: " + host.getId() + " Guid:" - + host.getGuid()); + s_logger.debug("Deleting Host: " + host.getId() + " Guid:" + host.getGuid()); } - User caller = _accountMgr.getActiveUser(UserContext.current() - .getCallerUserId()); + User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); - if (forceDestroyStorage) { - // put local storage into mainenance mode, will set all the VMs on - // this local storage into stopped state - StoragePoolVO storagePool = _storageMgr.findLocalStorageOnHost(host - .getId()); + if (forceDestroyStorage) { + // put local storage into mainenance mode, will set all the VMs on + // this local storage into stopped state + StoragePoolVO storagePool = _storageMgr.findLocalStorageOnHost(host.getId()); if (storagePool != null) { - if (storagePool.getStatus() == StoragePoolStatus.Up - || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) { - try { - StoragePool pool = _storageSvr - .preparePrimaryStorageForMaintenance(storagePool - .getId()); - if (pool == null) { - s_logger.debug("Failed to set primary storage into maintenance mode"); + if (storagePool.getStatus() == StoragePoolStatus.Up || storagePool.getStatus() == StoragePoolStatus.ErrorInMaintenance) { + try { + StoragePool pool = _storageSvr.preparePrimaryStorageForMaintenance(storagePool.getId()); + if (pool == null) { + s_logger.debug("Failed to set primary storage into maintenance mode"); - throw new UnableDeleteHostException( - "Failed to set primary storage into maintenance mode"); + throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode"); } } catch (Exception e) { - s_logger.debug("Failed to set primary storage into maintenance mode, due to: " - + e.toString()); - throw new UnableDeleteHostException( - "Failed to set primary storage into maintenance mode, due to: " - + e.toString()); + s_logger.debug("Failed to set primary storage into maintenance mode, due to: " + e.toString()); + throw new UnableDeleteHostException("Failed to set primary storage into maintenance mode, due to: " + e.toString()); } } - List vmsOnLocalStorage = _storageMgr - .listByStoragePool(storagePool.getId()); + List vmsOnLocalStorage = _storageMgr.listByStoragePool(storagePool.getId()); for (VMInstanceVO vm : vmsOnLocalStorage) { try { - if (!_vmMgr.destroy(vm, caller, - _accountMgr.getAccount(vm.getAccountId()))) { - String errorMsg = "There was an error Destory the vm: " - + vm - + " as a part of hostDelete id=" - + host.getId(); + if (!_vmMgr.destroy(vm, caller, _accountMgr.getAccount(vm.getAccountId()))) { + String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId(); s_logger.warn(errorMsg); throw new UnableDeleteHostException(errorMsg); } } catch (Exception e) { - String errorMsg = "There was an error Destory the vm: " - + vm + " as a part of hostDelete id=" - + host.getId(); + String errorMsg = "There was an error Destory the vm: " + vm + " as a part of hostDelete id=" + host.getId(); s_logger.debug(errorMsg, e); - throw new UnableDeleteHostException(errorMsg + "," - + e.getMessage()); + throw new UnableDeleteHostException(errorMsg + "," + e.getMessage()); } } } @@ -2457,45 +2164,26 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, // Stop HA disabled vms and HA enabled vms in Stopping state // Restart HA enabled vms for (VMInstanceVO vm : vms) { - if (!vm.isHaEnabled() - || vm.getState() == State.Stopping) { - s_logger.debug("Stopping vm: " + vm - + " as a part of deleteHost id=" - + host.getId()); + if (!vm.isHaEnabled() || vm.getState() == State.Stopping) { + s_logger.debug("Stopping vm: " + vm + " as a part of deleteHost id=" + host.getId()); try { - if (!_vmMgr.advanceStop(vm, true, caller, - _accountMgr.getAccount(vm - .getAccountId()))) { - String errorMsg = "There was an error stopping the vm: " - + vm - + " as a part of hostDelete id=" - + host.getId(); + if (!_vmMgr.advanceStop(vm, true, caller, _accountMgr.getAccount(vm.getAccountId()))) { + String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId(); s_logger.warn(errorMsg); - throw new UnableDeleteHostException( - errorMsg); + throw new UnableDeleteHostException(errorMsg); } } catch (Exception e) { - String errorMsg = "There was an error stopping the vm: " - + vm - + " as a part of hostDelete id=" - + host.getId(); + String errorMsg = "There was an error stopping the vm: " + vm + " as a part of hostDelete id=" + host.getId(); s_logger.debug(errorMsg, e); - throw new UnableDeleteHostException(errorMsg - + "," + e.getMessage()); - } - } else if (vm.isHaEnabled() - && (vm.getState() == State.Running || vm - .getState() == State.Starting)) { - s_logger.debug("Scheduling restart for vm: " + vm - + " " + vm.getState() + " on the host id=" - + host.getId()); + throw new UnableDeleteHostException(errorMsg + "," + e.getMessage()); + } + } else if (vm.isHaEnabled() && (vm.getState() == State.Running || vm.getState() == State.Starting)) { + s_logger.debug("Scheduling restart for vm: " + vm + " " + vm.getState() + " on the host id=" + host.getId()); _haMgr.scheduleRestart(vm, false); } } } else { - throw new UnableDeleteHostException( - "Unable to delete the host as there are vms in " - + vms.get(0).getState() + throw new UnableDeleteHostException("Unable to delete the host as there are vms in " + vms.get(0).getState() + " state using this host and isForced=false specified"); } } @@ -2510,35 +2198,31 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return true; } - /* - * TODO: think twice about returning true or throwing out exception, I - * really prefer to exception that always exposes bugs - */ - if (host.getResourceState() != ResourceState.PrepareForMaintenance - && host.getResourceState() != ResourceState.Maintenance - && host.getResourceState() != ResourceState.ErrorInMaintenance) { - throw new CloudRuntimeException( - "Cannot perform cancelMaintenance when resource state is " - + host.getResourceState() + ", hostId = " + hostId); + /* + * TODO: think twice about returning true or throwing out exception, I + * really prefer to exception that always exposes bugs + */ + if (host.getResourceState() != ResourceState.PrepareForMaintenance && host.getResourceState() != ResourceState.Maintenance + && host.getResourceState() != ResourceState.ErrorInMaintenance) { + throw new CloudRuntimeException("Cannot perform cancelMaintenance when resource state is " + host.getResourceState() + ", hostId = " + + hostId); } - /* TODO: move to listener */ + /* TODO: move to listener */ _haMgr.cancelScheduledMigrations(host); List vms = _haMgr.findTakenMigrationWork(); for (VMInstanceVO vm : vms) { if (vm.getHostId() != null && vm.getHostId() == hostId) { - s_logger.info("Unable to cancel migration because the vm is being migrated: " - + vm); + s_logger.info("Unable to cancel migration because the vm is being migrated: " + vm); return false; } } try { - resourceStateTransitTo(host, - ResourceState.Event.AdminCancelMaintenance, _nodeId); + resourceStateTransitTo(host, ResourceState.Event.AdminCancelMaintenance, _nodeId); _agentMgr.pullAgentOutMaintenance(hostId); - // for kvm, need to log into kvm host, restart cloudstack-agent + // for kvm, need to log into kvm host, restart cloudstack-agent if (host.getHypervisorType() == HypervisorType.KVM) { _hostDao.loadDetails(host); String password = host.getDetail("password"); @@ -2547,19 +2231,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, s_logger.debug("Can't find password/username"); return false; } - com.trilead.ssh2.Connection connection = SSHCmdHelper - .acquireAuthorizedConnection( - host.getPrivateIpAddress(), 22, username, - password); + com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection(host.getPrivateIpAddress(), 22, username, password); if (connection == null) { - s_logger.debug("Failed to connect to host: " - + host.getPrivateIpAddress()); + s_logger.debug("Failed to connect to host: " + host.getPrivateIpAddress()); return false; } try { - SSHCmdHelper.sshExecuteCmdOneShot(connection, - "service cloudstack-agent restart"); + SSHCmdHelper.sshExecuteCmdOneShot(connection, "service cloudstack-agent restart"); } catch (sshException e) { return false; } @@ -2567,16 +2246,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return true; } catch (NoTransitionException e) { - s_logger.debug("Cannot transmit host " + host.getId() - + "to Enabled state", e); + s_logger.debug("Cannot transmit host " + host.getId() + "to Enabled state", e); return false; } } private boolean cancelMaintenance(long hostId) { try { - Boolean result = _clusterMgr.propagateResourceEvent(hostId, - ResourceState.Event.AdminCancelMaintenance); + Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminCancelMaintenance); if (result != null) { return result; @@ -2589,49 +2266,42 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } @Override - public boolean executeUserRequest(long hostId, ResourceState.Event event) - throws AgentUnavailableException { + public boolean executeUserRequest(long hostId, ResourceState.Event event) throws AgentUnavailableException { if (event == ResourceState.Event.AdminAskMaintenace) { return doMaintain(hostId); } else if (event == ResourceState.Event.AdminCancelMaintenance) { return doCancelMaintenance(hostId); } else if (event == ResourceState.Event.DeleteHost) { - /* TODO: Ask alex why we assume the last two parameters are false */ + /* TODO: Ask alex why we assume the last two parameters are false */ return doDeleteHost(hostId, false, false); } else if (event == ResourceState.Event.Unmanaged) { return doUmanageHost(hostId); } else if (event == ResourceState.Event.UpdatePassword) { return doUpdateHostPassword(hostId); } else { - throw new CloudRuntimeException( - "Received an resource event we are not handling now, " - + event); + throw new CloudRuntimeException("Received an resource event we are not handling now, " + event); } } private boolean doUmanageHost(long hostId) { HostVO host = _hostDao.findById(hostId); if (host == null) { - s_logger.debug("Cannot find host " + hostId - + ", assuming it has been deleted, skip umanage"); + s_logger.debug("Cannot find host " + hostId + ", assuming it has been deleted, skip umanage"); return true; } if (host.getHypervisorType() == HypervisorType.KVM) { - MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, - new MaintainCommand()); + MaintainAnswer answer = (MaintainAnswer) _agentMgr.easySend(hostId, new MaintainCommand()); } - _agentMgr.disconnectWithoutInvestigation(hostId, - Event.ShutdownRequested); + _agentMgr.disconnectWithoutInvestigation(hostId, Event.ShutdownRequested); return true; } @Override public boolean umanageHost(long hostId) { try { - Boolean result = _clusterMgr.propagateResourceEvent(hostId, - ResourceState.Event.Unmanaged); + Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.Unmanaged); if (result != null) { return result; @@ -2653,8 +2323,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, String username = nv.getValue(); nv = _hostDetailsDao.findDetail(hostId, ApiConstants.PASSWORD); String password = nv.getValue(); - UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(username, - password); + UpdateHostPasswordCommand cmd = new UpdateHostPasswordCommand(username, password); attache.updatePassword(cmd); return true; } @@ -2664,8 +2333,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, if (cmd.getClusterId() == null) { // update agent attache password try { - Boolean result = _clusterMgr.propagateResourceEvent( - cmd.getHostId(), ResourceState.Event.UpdatePassword); + Boolean result = _clusterMgr.propagateResourceEvent(cmd.getHostId(), ResourceState.Event.UpdatePassword); if (result != null) { return result; } @@ -2678,12 +2346,11 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, List hosts = this.listAllHostsInCluster(cmd.getClusterId()); for (HostVO h : hosts) { try { - /* - * FIXME: this is a buggy logic, check with alex. Shouldn't - * return if propagation return non null - */ - Boolean result = _clusterMgr.propagateResourceEvent( - h.getId(), ResourceState.Event.UpdatePassword); + /* + * FIXME: this is a buggy logic, check with alex. Shouldn't + * return if propagation return non null + */ + Boolean result = _clusterMgr.propagateResourceEvent(h.getId(), ResourceState.Event.UpdatePassword); if (result != null) { return result; } @@ -2707,14 +2374,10 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return false; } else { try { - return resourceStateTransitTo(host, - ResourceState.Event.UnableToMigrate, _nodeId); + return resourceStateTransitTo(host, ResourceState.Event.UnableToMigrate, _nodeId); } catch (NoTransitionException e) { - s_logger.debug( - "No next resource state for host " + host.getId() - + " while current state is " - + host.getResourceState() + " with event " - + ResourceState.Event.UnableToMigrate, e); + s_logger.debug("No next resource state for host " + host.getId() + " while current state is " + host.getResourceState() + + " with event " + ResourceState.Event.UnableToMigrate, e); return false; } } @@ -2723,19 +2386,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public List findDirectlyConnectedHosts() { /* The resource column is not null for direct connected resource */ - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getResource(), Op.NNULL); - sc.addAnd(sc.getEntity().getResourceState(), Op.NIN, - ResourceState.Disabled); + sc.addAnd(sc.getEntity().getResourceState(), Op.NIN, ResourceState.Disabled); return sc.list(); } @Override - public List listAllUpAndEnabledHosts(Type type, Long clusterId, - Long podId, long dcId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + public List listAllUpAndEnabledHosts(Type type, Long clusterId, Long podId, long dcId) { + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); if (type != null) { sc.addAnd(sc.getEntity().getType(), Op.EQ, type); } @@ -2747,23 +2406,19 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, } sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); - sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, - ResourceState.Enabled); + sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, ResourceState.Enabled); return sc.list(); } @Override - public List listAllUpAndEnabledNonHAHosts(Type type, - Long clusterId, Long podId, long dcId) { + public List listAllUpAndEnabledNonHAHosts(Type type, Long clusterId, Long podId, long dcId) { String haTag = _haMgr.getHaTag(); - return _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, - dcId, haTag); + return _hostDao.listAllUpAndEnabledNonHAHosts(type, clusterId, podId, dcId, haTag); } @Override public List findHostByGuid(long dcId, String guid) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); sc.addAnd(sc.getEntity().getGuid(), Op.EQ, guid); return sc.list(); @@ -2771,53 +2426,44 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public List listAllHostsInCluster(long clusterId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getClusterId(), Op.EQ, clusterId); return sc.list(); } @Override public List listHostsInClusterByStatus(long clusterId, Status status) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getClusterId(), Op.EQ, clusterId); sc.addAnd(sc.getEntity().getStatus(), Op.EQ, status); return sc.list(); } @Override - public List listAllUpAndEnabledHostsInOneZoneByType(Type type, - long dcId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + public List listAllUpAndEnabledHostsInOneZoneByType(Type type, long dcId) { + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getType(), Op.EQ, type); sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); - sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, - ResourceState.Enabled); + sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, ResourceState.Enabled); return sc.list(); } @Override - public List listAllNotInMaintenanceHostsInOneZone(Type type, - Long dcId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); - if (dcId != null) { + public List listAllNotInMaintenanceHostsInOneZone(Type type, Long dcId) { + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); + if (dcId != null) { sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); } sc.addAnd(sc.getEntity().getType(), Op.EQ, type); - sc.addAnd(sc.getEntity().getResourceState(), Op.NIN, - ResourceState.Maintenance, ResourceState.ErrorInMaintenance, - ResourceState.PrepareForMaintenance, ResourceState.Error); + sc.addAnd(sc.getEntity().getResourceState(), Op.NIN, ResourceState.Maintenance, ResourceState.ErrorInMaintenance, + ResourceState.PrepareForMaintenance, ResourceState.Error); return sc.list(); } @Override public List listAllHostsInOneZoneByType(Type type, long dcId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getType(), Op.EQ, type); sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); return sc.list(); @@ -2825,17 +2471,14 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public List listAllHostsInAllZonesByType(Type type) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getType(), Op.EQ, type); return sc.list(); } @Override - public List listAvailHypervisorInZone(Long hostId, - Long zoneId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + public List listAvailHypervisorInZone(Long hostId, Long zoneId) { + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); if (zoneId != null) { sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, zoneId); } @@ -2854,35 +2497,30 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public HostVO findHostByGuid(String guid) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getGuid(), Op.EQ, guid); return sc.find(); } @Override public HostVO findHostByName(String name) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getName(), Op.EQ, name); return sc.find(); } @Override public List listHostsByNameLike(String name) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getName(), Op.LIKE, "%" + name + "%"); return sc.list(); } @Override - public Pair findPod(VirtualMachineTemplate template, - ServiceOfferingVO offering, DataCenterVO dc, long accountId, - Set avoids) { - for (PodAllocator allocator : _podAllocators) { - final Pair pod = allocator.allocateTo(template, - offering, dc, accountId, avoids); + public Pair findPod(VirtualMachineTemplate template, ServiceOfferingVO offering, DataCenterVO dc, long accountId, + Set avoids) { + for (PodAllocator allocator : _podAllocators) { + final Pair pod = allocator.allocateTo(template, offering, dc, accountId, avoids); if (pod != null) { return pod; } @@ -2892,9 +2530,8 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Override public HostStats getHostStatistics(long hostId) { - Answer answer = _agentMgr.easySend(hostId, new GetHostStatsCommand( - _hostDao.findById(hostId).getGuid(), _hostDao.findById(hostId) - .getName(), hostId)); + Answer answer = _agentMgr.easySend(hostId, new GetHostStatsCommand(_hostDao.findById(hostId).getGuid(), _hostDao.findById(hostId).getName(), + hostId)); if (answer != null && (answer instanceof UnsupportedAnswer)) { return null; @@ -2921,8 +2558,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return null; } else { _hostDao.loadDetails(host); - DetailVO detail = _hostDetailsDao.findDetail(hostId, - "guest.os.category.id"); + DetailVO detail = _hostDetailsDao.findDetail(hostId, "guest.os.category.id"); if (detail == null) { return null; } else { @@ -2958,16 +2594,13 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return pcs; } - @Override - public List listAllUpAndEnabledHostsInOneZoneByHypervisor( - HypervisorType type, long dcId) { - SearchCriteriaService sc = SearchCriteria2 - .create(HostVO.class); + @Override + public List listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType type, long dcId) { + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getHypervisorType(), Op.EQ, type); sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); - sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, - ResourceState.Enabled); + sc.addAnd(sc.getEntity().getResourceState(), Op.EQ, ResourceState.Enabled); return sc.list(); - } + } } diff --git a/server/src/com/cloud/storage/s3/S3Manager.java b/server/src/com/cloud/storage/s3/S3Manager.java index 0f74e431376..14da1da3577 100644 --- a/server/src/com/cloud/storage/s3/S3Manager.java +++ b/server/src/com/cloud/storage/s3/S3Manager.java @@ -19,6 +19,7 @@ package com.cloud.storage.s3; import java.util.List; +import java.util.Map; import com.cloud.agent.api.to.S3TO; import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; @@ -40,6 +41,8 @@ public interface S3Manager extends Manager { S3 addS3(AddS3Cmd addS3Cmd) throws DiscoveryException; + void verifyS3Fields(Map params) throws DiscoveryException; + Long chooseZoneForTemplateExtract(VMTemplateVO template); boolean isS3Enabled(); diff --git a/server/src/com/cloud/storage/s3/S3ManagerImpl.java b/server/src/com/cloud/storage/s3/S3ManagerImpl.java index 61e5573394d..06106db432c 100644 --- a/server/src/com/cloud/storage/s3/S3ManagerImpl.java +++ b/server/src/com/cloud/storage/s3/S3ManagerImpl.java @@ -46,6 +46,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; import org.apache.log4j.Logger; @@ -89,12 +90,13 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { private static final Logger LOGGER = Logger.getLogger(S3ManagerImpl.class); - @Inject + @Inject private AgentManager agentManager; @Inject private S3Dao s3Dao; + @Inject private VMTemplateZoneDao vmTemplateZoneDao; @@ -121,7 +123,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { public S3ManagerImpl() { } - + private void verifyConnection(final S3TO s3) throws DiscoveryException { if (!canConnect(s3)) { @@ -247,6 +249,26 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { } + + @Override + public void verifyS3Fields(Map params) throws DiscoveryException { + final S3VO s3VO = new S3VO(UUID.randomUUID().toString(), + params.get(ApiConstants.S3_ACCESS_KEY), + params.get(ApiConstants.S3_SECRET_KEY), + params.get(ApiConstants.S3_END_POINT), + params.get(ApiConstants.S3_BUCKET_NAME), + Boolean.valueOf(params.get(ApiConstants.S3_HTTPS_FLAG)), + Integer.valueOf(params.get(ApiConstants.S3_CONNECTION_TIMEOUT)), + Integer.valueOf(params.get(ApiConstants.S3_MAX_ERROR_RETRY)), + Integer.valueOf(params.get(ApiConstants.S3_SOCKET_TIMEOUT)), now()); + + this.validateFields(s3VO); + + final S3TO s3 = s3VO.toS3TO(); + this.verifyConnection(s3); + this.verifyBuckets(s3); + } + @Override public boolean isS3Enabled() { return Boolean diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/test/com/cloud/resource/MockResourceManagerImpl.java index df62d2e6bc9..da4d3fb67c3 100644 --- a/server/test/com/cloud/resource/MockResourceManagerImpl.java +++ b/server/test/com/cloud/resource/MockResourceManagerImpl.java @@ -49,7 +49,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster; import com.cloud.resource.ResourceState.Event; import com.cloud.service.ServiceOfferingVO; -import com.cloud.storage.ObjectStore; +import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.Swift; import com.cloud.template.VirtualMachineTemplate; @@ -610,7 +610,7 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana } @Override - public ObjectStore discoverObjectStore(AddSecondaryStorageCmd cmd) throws IllegalArgumentException, DiscoveryException, + public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { // TODO Auto-generated method stub return null; diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ed954619f49..38bad7ab9de 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -68,54 +68,53 @@ CREATE TABLE `cloud`.`object_datastore_ref` ( -- PRIMARY KEY(`id`) -- ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`image_data_store` ( +CREATE TABLE `cloud`.`image_store` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', `name` varchar(255) NOT NULL COMMENT 'name of data store', - `image_provider_name` varchar(255) NOT NULL COMMENT 'id of image_data_store_provider', + `image_provider_name` varchar(255) NOT NULL COMMENT 'id of image_store_provider', `protocol` varchar(255) NOT NULL COMMENT 'protocol of data store', `url` varchar(255) COMMENT 'url for image data store', `data_center_id` bigint unsigned COMMENT 'datacenter id of data store', - `region_id` bigint unsigned COMMENT 'region id of data store', `scope` varchar(255) COMMENT 'scope of data store', `uuid` varchar(255) COMMENT 'uuid of data store', + `state` varchar(30) COMMENT 'state of data store', + `created` datetime COMMENT 'date the image store first signed on', + `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -CREATE TABLE `cloud`.`image_data_store_details` ( +CREATE TABLE `cloud`.`image_store_details` ( `id` bigint unsigned UNIQUE NOT NULL AUTO_INCREMENT COMMENT 'id', `store_id` bigint unsigned NOT NULL COMMENT 'store the detail is related to', `name` varchar(255) NOT NULL COMMENT 'name of the detail', `value` varchar(255) NOT NULL COMMENT 'value of the detail', PRIMARY KEY (`id`), - CONSTRAINT `fk_image_data_store_details__store_id` FOREIGN KEY `fk_image_data_store__store_id`(`store_id`) REFERENCES `image_data_store`(`id`) ON DELETE CASCADE, - INDEX `i_image_data_store__name__value`(`name`(128), `value`(128)) + CONSTRAINT `fk_image_store_details__store_id` FOREIGN KEY `fk_image_store__store_id`(`store_id`) REFERENCES `image_store`(`id`) ON DELETE CASCADE, + INDEX `i_image_store__name__value`(`name`(128), `value`(128)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -DROP VIEW IF EXISTS `cloud`.`image_data_store_view`; -CREATE VIEW `cloud`.`image_data_store_view` AS +DROP VIEW IF EXISTS `cloud`.`image_store_view`; +CREATE VIEW `cloud`.`image_store_view` AS select - image_data_store.id, - image_data_store.uuid, - image_data_store.name, - image_data_store.provider_name, - image_data_store.protocol, - image_data_store.url, - image_data_store.scope, + image_store.id, + image_store.uuid, + image_store.name, + image_store.image_provider_name, + image_store.protocol, + image_store.url, + image_store.scope, + image_store.state, data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, - region.id region_id, - region.name region_name, - image_data_store_details.name detail_name, - image_data_store_details.value detail_value + image_store_details.name detail_name, + image_store_details.value detail_value from - `cloud`.`image_data_store` + `cloud`.`image_store` left join - `cloud`.`data_center` ON image_data_store.data_center_id = data_center.id + `cloud`.`data_center` ON image_store.data_center_id = data_center.id left join - `cloud`.`region` ON image_data_store.region_id = region.id - left join - `cloud`.`image_data_store_details` ON image_data_store_details.store_id = image_data_store.id; + `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id; CREATE TABLE `cloud`.`template_store_ref` ( From 848fea6069823d6dab43d2eb70ba636031404a0f Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 8 Apr 2013 11:36:53 -0700 Subject: [PATCH 008/303] Add ListImageStoresCmd api. --- .../admin/storage/ListImageStoresCmd.java | 111 ++++++++++++++++++ .../apache/cloudstack/query/QueryService.java | 4 + client/tomcatconf/commands.properties.in | 4 + .../src/com/cloud/api/ApiResponseHelper.java | 2 +- .../com/cloud/api/query/QueryManagerImpl.java | 108 ++++++++++++++++- .../cloud/api/query/ViewResponseHelper.java | 2 +- 6 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java new file mode 100644 index 00000000000..4dbe9006ee9 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java @@ -0,0 +1,111 @@ +// 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 org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseListCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.response.ClusterResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.api.response.PodResponse; +import org.apache.cloudstack.api.response.StoragePoolResponse; +import org.apache.cloudstack.api.response.ZoneResponse; +import org.apache.log4j.Logger; + +import com.cloud.async.AsyncJob; + +@APICommand(name = "listImageStores", description="Lists image stores.", responseObject=ImageStoreResponse.class) +public class ListImageStoresCmd extends BaseListCmd { + public static final Logger s_logger = Logger.getLogger(ListImageStoresCmd.class.getName()); + + private static final String s_name = "listimagestoreresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the image store") + private String storeName; + + @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="the image store state") + private String state; + + @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="the image store protocol") + private String protocol; + + @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, description="the image store provider") + private String provider; + + @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.ID, type=CommandType.UUID, entityType = StoragePoolResponse.class, + description="the ID of the storage pool") + private Long id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + + + public Long getZoneId() { + return zoneId; + } + + public String getStoreName() { + return storeName; + } + + public String getState() { + return state; + } + + public String getProtocol() { + return protocol; + } + + public Long getId() { + return id; + } + + public String getProvider() { + return provider; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + + @Override + public String getCommandName() { + return s_name; + } + + + @Override + public void execute(){ + ListResponse response = _queryService.searchForImageStores(this); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } +} diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index c3f86aabb7f..66f63993dfd 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.query; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; +import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; @@ -40,6 +41,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; @@ -88,6 +90,8 @@ public interface QueryService { public ListResponse searchForStoragePools(ListStoragePoolsCmd cmd); + public ListResponse searchForImageStores(ListImageStoresCmd cmd); + public ListResponse searchForAccounts(ListAccountsCmd cmd); public ListResponse searchForAsyncJobs(ListAsyncJobsCmd cmd); diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index ad17c1512d4..d2828493f34 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -243,6 +243,10 @@ listS3s=1 #### image store commands addImageStore=1 +listImageStores=1 +deleteImageStore=1 +enableImageStore=1 + #### host commands addHost=3 diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 527204556df..e9255c452f4 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -894,7 +894,7 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public ImageStoreResponse createImageStoreResponse(ImageStore os) { List viewStores = ApiDBUtils.newImageStoreView(os); - List listStores = ViewResponseHelper.createObjectStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()])); + List listStores = ViewResponseHelper.createImageStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()])); assert listStores != null && listStores.size() == 1 : "There should be one image data store returned"; return listStores.get(0); diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 951d09ed185..daf49cbddac 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -29,6 +29,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; +import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd; import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd; import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; @@ -51,6 +52,7 @@ import org.apache.cloudstack.api.response.DiskOfferingResponse; import org.apache.cloudstack.api.response.DomainRouterResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.HostResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.InstanceGroupResponse; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.ProjectAccountResponse; @@ -74,6 +76,7 @@ import com.cloud.api.query.dao.DataCenterJoinDao; import com.cloud.api.query.dao.DiskOfferingJoinDao; import com.cloud.api.query.dao.DomainRouterJoinDao; import com.cloud.api.query.dao.HostJoinDao; +import com.cloud.api.query.dao.ImageStoreJoinDao; import com.cloud.api.query.dao.InstanceGroupJoinDao; import com.cloud.api.query.dao.ProjectAccountJoinDao; import com.cloud.api.query.dao.ProjectInvitationJoinDao; @@ -92,6 +95,7 @@ import com.cloud.api.query.vo.DiskOfferingJoinVO; import com.cloud.api.query.vo.DomainRouterJoinVO; import com.cloud.api.query.vo.EventJoinVO; import com.cloud.api.query.vo.HostJoinVO; +import com.cloud.api.query.vo.ImageStoreJoinVO; import com.cloud.api.query.vo.InstanceGroupJoinVO; import com.cloud.api.query.vo.ProjectAccountJoinVO; import com.cloud.api.query.vo.ProjectInvitationJoinVO; @@ -126,6 +130,8 @@ import com.cloud.projects.dao.ProjectDao; import com.cloud.server.Criteria; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.ImageStore; +import com.cloud.storage.ScopeType; import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -228,6 +234,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Inject private StoragePoolJoinDao _poolJoinDao; + @Inject + private ImageStoreJoinDao _imageStoreJoinDao; + @Inject private DiskOfferingJoinDao _diskOfferingJoinDao; @@ -1843,7 +1852,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { SearchBuilder sb = _poolJoinDao.createSearchBuilder(); sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); - sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("path", sb.entity().getPath(), SearchCriteria.Op.EQ); sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("podId", sb.entity().getPodId(), SearchCriteria.Op.EQ); @@ -1867,7 +1876,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (name != null) { - sc.setParameters("name", "%" + name + "%"); + sc.setParameters("name", name); } if (path != null) { @@ -1904,6 +1913,101 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } + + @Override + public ListResponse searchForImageStores(ListImageStoresCmd cmd) { + Pair, Integer> result = searchForImageStoresInternal(cmd); + ListResponse response = new ListResponse(); + + List poolResponses = ViewResponseHelper.createImageStoreResponse(result.first().toArray(new ImageStoreJoinVO[result.first().size()])); + response.setResponses(poolResponses, result.second()); + return response; + } + + private Pair, Integer> searchForImageStoresInternal(ListImageStoresCmd cmd) { + + Long zoneId = _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), cmd.getZoneId()); + Object id = cmd.getId(); + Object name = cmd.getStoreName(); + String provider = cmd.getProvider(); + String protocol = cmd.getProtocol(); + ImageStore.State state = null; + String stateStr = cmd.getState(); + if (stateStr != null) { + try { + state = Enum.valueOf(ImageStore.State.class, stateStr.toUpperCase()); + } catch (Exception e) { + throw new InvalidParameterValueException("invalid state" + stateStr); + } + } + Object keyword = cmd.getKeyword(); + Long startIndex = cmd.getStartIndex(); + Long pageSize = cmd.getPageSizeVal(); + + + Filter searchFilter = new Filter(ImageStoreJoinVO.class, "id", Boolean.TRUE, startIndex, pageSize); + + SearchBuilder sb = _imageStoreJoinDao.createSearchBuilder(); + sb.select(null, Func.DISTINCT, sb.entity().getId()); // select distinct ids + sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); + sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); + sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); + sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ); + sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); + sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ); + + + SearchCriteria sc = sb.create(); + + + if (keyword != null) { + SearchCriteria ssc = _imageStoreJoinDao.createSearchCriteria(); + ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + ssc.addOr("provider", SearchCriteria.Op.LIKE, "%" + keyword + "%" ); + sc.addAnd("name", SearchCriteria.Op.SC, ssc); + } + + if (id != null) { + sc.setParameters("id", id); + } + + if (name != null) { + sc.setParameters("name", name); + } + + + if (zoneId != null) { + sc.setParameters("dataCenterId", zoneId); + } + if (provider != null) { + sc.setParameters("provider", provider); + } + if (state != null) { + sc.setParameters("state", state); + } + if (protocol != null) { + sc.setParameters("protocol", protocol); + } + + // search Store details by ids + Pair, Integer> uniqueStorePair = _imageStoreJoinDao.searchAndCount(sc, searchFilter); + Integer count = uniqueStorePair.second(); + if (count.intValue() == 0) { + // empty result + return uniqueStorePair; + } + List uniqueStores = uniqueStorePair.first(); + Long[] vrIds = new Long[uniqueStores.size()]; + int i = 0; + for (ImageStoreJoinVO v : uniqueStores) { + vrIds[i++] = v.getId(); + } + List vrs = _imageStoreJoinDao.searchByIds(vrIds); + return new Pair, Integer>(vrs, count); + + } + + @Override public ListResponse searchForDiskOfferings(ListDiskOfferingsCmd cmd) { Pair, Integer> result = searchForDiskOfferingsInternal(cmd); diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 90b900c57a3..5b3c9346d9b 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -265,7 +265,7 @@ public class ViewResponseHelper { return new ArrayList(vrDataList.values()); } - public static List createObjectStoreResponse(ImageStoreJoinVO... stores) { + public static List createImageStoreResponse(ImageStoreJoinVO... stores) { Hashtable vrDataList = new Hashtable(); // Initialise the vrdatalist with the input data for (ImageStoreJoinVO vr : stores) { From 7f64b61cbd1cf81c610d23559354dd778b32321c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 8 Apr 2013 14:16:51 -0700 Subject: [PATCH 009/303] Move some image store related interface methods from ResourceService to StorageService. --- .../com/cloud/resource/ResourceService.java | 3 - api/src/com/cloud/storage/StorageService.java | 9 ++ .../admin/storage/AddImageStoreCmd.java | 2 +- .../admin/storage/DeleteImageStoreCmd.java | 80 +++++++++++++ .../cloud/resource/ResourceManagerImpl.java | 71 +----------- .../com/cloud/storage/StorageManagerImpl.java | 105 ++++++++++++++++-- .../resource/MockResourceManagerImpl.java | 8 -- 7 files changed, 184 insertions(+), 94 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java index d8c09d9662c..268bcd61770 100755 --- a/api/src/com/cloud/resource/ResourceService.java +++ b/api/src/com/cloud/resource/ResourceService.java @@ -27,7 +27,6 @@ import org.apache.cloudstack.api.command.admin.host.PrepareForMaintenanceCmd; import org.apache.cloudstack.api.command.admin.host.ReconnectHostCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostCmd; import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd; -import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; @@ -39,7 +38,6 @@ import com.cloud.exception.ResourceInUseException; import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster; -import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.Swift; import com.cloud.utils.Pair; @@ -103,7 +101,6 @@ public interface ResourceService { S3 discoverS3(AddS3Cmd cmd) throws DiscoveryException; - ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; List getSupportedHypervisorTypes(long zoneId, boolean forVirtualRouter, Long podId); diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 63c5023ee91..ee1a9565be4 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -18,12 +18,16 @@ package com.cloud.storage; 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.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; +import com.cloud.exception.DiscoveryException; import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceInUseException; import com.cloud.exception.ResourceUnavailableException; @@ -82,4 +86,9 @@ public interface StorageService{ public StoragePool updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException; public StoragePool getStoragePool(long id); + + boolean deleteImageStore(DeleteImageStoreCmd cmd); + + ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; + } diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index 40ae6b26e84..511283f6626 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -102,7 +102,7 @@ public class AddImageStoreCmd extends BaseCmd { @Override public void execute(){ try{ - ImageStore result = _resourceService.discoverImageStore(this); + ImageStore result = _storageService.discoverImageStore(this); ImageStoreResponse storeResponse = null; if (result != null ) { storeResponse = _responseGenerator.createImageStoreResponse(result); diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java new file mode 100644 index 00000000000..34a4ae076cb --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java @@ -0,0 +1,80 @@ +// 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 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.response.HostResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.log4j.Logger; + +import com.cloud.user.Account; + +@APICommand(name = "deleteImageStore", description = "Deletes an image store .", responseObject = SuccessResponse.class) +public class DeleteImageStoreCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(DeleteImageStoreCmd.class.getName()); + + private static final String s_name = "deleteimagestoreresponse"; + + // /////////////////////////////////////////////////// + // ////////////// API parameters ///////////////////// + // /////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ImageStoreResponse.class, + required = true, description = "the image store ID") + private Long id; + + + // /////////////////////////////////////////////////// + // ///////////////// Accessors /////////////////////// + // /////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + + // /////////////////////////////////////////////////// + // ///////////// API Implementation/////////////////// + // /////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute() { + boolean result = _storageService.deleteImageStore(this); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete image store"); + } + } +} diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index 27df1affb20..ef567694733 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -176,8 +176,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, @Inject protected SecondaryStorageVmManager _secondaryStorageMgr; @Inject - DataStoreProviderManager _dataStoreProviderMgr; - @Inject protected RegionDao _regionDao; @Inject protected DataCenterDao _dcDao; @@ -217,8 +215,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, protected HighAvailabilityManager _haMgr; @Inject protected StorageService _storageSvr; - @Inject - DataStoreManager _dataStoreMgr; + protected List _discoverers; @@ -633,72 +630,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager, return this._s3Mgr.listS3s(cmd); } - @Override - public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, - InvalidParameterValueException { - String providerName = cmd.getProviderName(); - DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); - - if (storeProvider == null) { - storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider(); - if (storeProvider == null) { - throw new InvalidParameterValueException("can't find image store provider: " + providerName); - } - } - - Long dcId = cmd.getZoneId(); - String url = cmd.getUrl(); - Map details = cmd.getDetails(); - - ScopeType scopeType = null; - String scope = cmd.getScope(); - if (scope != null) { - try { - scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); - } catch (Exception e) { - throw new InvalidParameterValueException("invalid scope" + scope); - } - } - if (scopeType == ScopeType.ZONE && dcId == null) { - throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); - } - - if (dcId != null) { - // Check if the zone exists in the system - DataCenterVO zone = _dcDao.findById(dcId); - if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " + dcId); - } - - Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { - PermissionDeniedException ex = new PermissionDeniedException( - "Cannot perform this operation, Zone with specified id is currently disabled"); - ex.addProxyObject(zone, dcId, "dcId"); - throw ex; - } - } - - - Map params = new HashMap(); - params.put("zoneId", dcId); - params.put("url", cmd.getUrl()); - params.put("name", cmd.getUrl()); - params.put("details", details); - params.put("scope", scopeType); - params.put("providerName", storeProvider.getName()); - - DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); - DataStore store = null; - try { - store = lifeCycle.initialize(params); - } catch (Exception e) { - s_logger.debug("Failed to add data store", e); - throw new CloudRuntimeException("Failed to add data store", e); - } - - return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); - } private List discoverHostsFull(Long dcId, Long podId, Long clusterId, String clusterName, String url, String username, String password, String hypervisorType, List hostTags, Map params, boolean deferAgentCreation) throws IllegalArgumentException, diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 72a0e0741f2..88b1a520dd6 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -40,8 +40,10 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +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.CreateStoragePoolCmd; +import org.apache.cloudstack.api.command.admin.storage.DeleteImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.DeletePoolCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; @@ -103,6 +105,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; +import com.cloud.exception.DiscoveryException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; @@ -294,6 +297,11 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected ResourceTagDao _resourceTagDao; + @Inject + DataStoreManager _dataStoreMgr; + @Inject + DataStoreProviderManager _dataStoreProviderMgr; + protected List _storagePoolAllocators; public List getStoragePoolAllocators() { return _storagePoolAllocators; @@ -453,13 +461,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C VirtualMachineProfile profile = new VirtualMachineProfileImpl( vm); for (StoragePoolAllocator allocator : _storagePoolAllocators) { - + ExcludeList avoidList = new ExcludeList(); for(StoragePool pool : avoid){ avoidList.addPool(pool.getId()); } DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), clusterId, hostId, null, null); - + final List poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1); if (poolList != null && !poolList.isEmpty()) { return (StoragePool)this.dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary); @@ -672,7 +680,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return true; } - + @Override public String getStoragePoolTags(long poolId) { return _configMgr.listToCsvTags(_storagePoolDao @@ -701,7 +709,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return true; } - + @DB @Override public DataStore createLocalStorage(Host host, StoragePoolInfo pInfo) throws ConnectionException { @@ -715,7 +723,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C StoragePoolVO pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), pInfo.getHostPath(), pInfo.getUuid()); if(pool == null && host.getHypervisorType() == HypervisorType.VMware) { // perform run-time upgrade. In versions prior to 2.2.12, there is a bug that we don't save local datastore info (host path is empty), this will cause us - // not able to distinguish multiple local datastores that may be available on the host, to support smooth migration, we + // not able to distinguish multiple local datastores that may be available on the host, to support smooth migration, we // need to perform runtime upgrade here if(pInfo.getHostPath().length() > 0) { pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), "", pInfo.getUuid()); @@ -735,13 +743,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C params.put("details", pInfo.getDetails()); params.put("uuid", pInfo.getUuid()); params.put("providerName", provider.getName()); - + store = lifeCycle.initialize(params); } else { store = (DataStore) dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); } - + HostScope scope = new HostScope(host.getId()); lifeCycle.attachHost(store, scope, pInfo); } catch (Exception e) { @@ -1007,7 +1015,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } CapacityState capacityState = (allocationState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled; - + capacity.setCapacityState(capacityState); _capacityDao.persist(capacity); } else { @@ -1147,7 +1155,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C }finally { scanLock.unlock(); } - } + } }finally { scanLock.releaseRef(); } @@ -1479,7 +1487,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStore store = dataStoreMgr.getDataStore( primaryStorage.getId(), DataStoreRole.Primary); lifeCycle.cancelMaintain(store); - + return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore( primaryStorage.getId(), DataStoreRole.Primary); } @@ -1627,7 +1635,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStoreRole.Primary); } - + @Override @DB @@ -1708,7 +1716,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return secHost; } - + @Override public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) { @@ -1875,4 +1883,77 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return null; } + @Override + public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, + InvalidParameterValueException { + String providerName = cmd.getProviderName(); + DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); + + if (storeProvider == null) { + storeProvider = _dataStoreProviderMgr.getDefaultImageDataStoreProvider(); + if (storeProvider == null) { + throw new InvalidParameterValueException("can't find image store provider: " + providerName); + } + } + + Long dcId = cmd.getZoneId(); + String url = cmd.getUrl(); + Map details = cmd.getDetails(); + + ScopeType scopeType = null; + String scope = cmd.getScope(); + if (scope != null) { + try { + scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); + } catch (Exception e) { + throw new InvalidParameterValueException("invalid scope" + scope); + } + } + if (scopeType == ScopeType.ZONE && dcId == null) { + throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); + } + + if (dcId != null) { + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(dcId); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + dcId); + } + + Account account = UserContext.current().getCaller(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + PermissionDeniedException ex = new PermissionDeniedException( + "Cannot perform this operation, Zone with specified id is currently disabled"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; + } + } + + + Map params = new HashMap(); + params.put("zoneId", dcId); + params.put("url", cmd.getUrl()); + params.put("name", cmd.getUrl()); + params.put("details", details); + params.put("scope", scopeType); + params.put("providerName", storeProvider.getName()); + + DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); + DataStore store = null; + try { + store = lifeCycle.initialize(params); + } catch (Exception e) { + s_logger.debug("Failed to add data store", e); + throw new CloudRuntimeException("Failed to add data store", e); + } + + return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); + } + @Override + public boolean deleteImageStore(DeleteImageStoreCmd cmd) { + // TODO Auto-generated method stub + return false; + } + + } diff --git a/server/test/com/cloud/resource/MockResourceManagerImpl.java b/server/test/com/cloud/resource/MockResourceManagerImpl.java index da4d3fb67c3..819120bfa8b 100644 --- a/server/test/com/cloud/resource/MockResourceManagerImpl.java +++ b/server/test/com/cloud/resource/MockResourceManagerImpl.java @@ -609,12 +609,4 @@ public class MockResourceManagerImpl extends ManagerBase implements ResourceMana return null; } - @Override - public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, - InvalidParameterValueException { - // TODO Auto-generated method stub - return null; - } - - } From 74880fa26f4dcf5248e66e1e4517af2cb95376c5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 8 Apr 2013 16:18:06 -0700 Subject: [PATCH 010/303] add DeleteImageStoreCmd Api. --- .../storage/datastore}/db/ImageStoreDao.java | 2 +- .../datastore}/db/ImageStoreDetailVO.java | 2 +- .../datastore}/db/ImageStoreDetailsDao.java | 5 +- .../storage/datastore}/db/ImageStoreVO.java | 2 +- .../datastore}/db/SnapshotDataStoreDao.java | 12 +++- .../datastore}/db/SnapshotDataStoreVO.java | 2 +- .../datastore}/db/TemplateDataStoreDao.java | 10 +++- .../datastore}/db/TemplateDataStoreVO.java | 2 +- .../datastore}/db/VolumeDataStoreDao.java | 9 ++- .../datastore}/db/VolumeDataStoreVO.java | 2 +- .../ImageStoreProviderManagerImpl.java | 4 +- .../storage/image/store/ImageStoreImpl.java | 2 +- .../storage}/db/DataStoreProviderDaoImpl.java | 4 +- .../image/datastore/ImageStoreHelper.java | 8 +-- .../storage/image/db/ImageStoreDaoImpl.java | 2 + .../image/db/ImageStoreDetailsDaoImpl.java | 17 ++++++ .../db/SnapshotDataStoreDaoImpl.java | 58 +++++++++++++++--- .../db/TemplateDataStoreDaoImpl.java | 45 +++++++++++++- .../db/VolumeDataStoreDaoImpl.java | 34 ++++++++++- .../db/PrimaryDataStoreDetailsDaoImpl.java | 5 +- .../CloudStackImageStoreLifeCycleImpl.java | 4 +- .../lifecycle/S3ImageStoreLifeCycleImpl.java | 4 +- .../SampleImageStoreLifeCycleImpl.java | 4 +- .../SwiftImageStoreLifeCycleImpl.java | 4 +- .../com/cloud/storage/StorageManagerImpl.java | 60 ++++++++++++++++++- 25 files changed, 262 insertions(+), 41 deletions(-) rename engine/{storage/src/org/apache/cloudstack/storage/image => api/src/org/apache/cloudstack/storage/datastore}/db/ImageStoreDao.java (94%) rename engine/{storage/src/org/apache/cloudstack/storage/image => api/src/org/apache/cloudstack/storage/datastore}/db/ImageStoreDetailVO.java (97%) rename engine/{storage/src/org/apache/cloudstack/storage/image => api/src/org/apache/cloudstack/storage/datastore}/db/ImageStoreDetailsDao.java (92%) rename engine/{storage/src/org/apache/cloudstack/storage/image => api/src/org/apache/cloudstack/storage/datastore}/db/ImageStoreVO.java (98%) rename engine/{storage/src/org/apache/cloudstack/storage => api/src/org/apache/cloudstack/storage/datastore}/db/SnapshotDataStoreDao.java (68%) rename engine/{storage/src/org/apache/cloudstack/storage => api/src/org/apache/cloudstack/storage/datastore}/db/SnapshotDataStoreVO.java (99%) rename engine/{storage/src/org/apache/cloudstack/storage => api/src/org/apache/cloudstack/storage/datastore}/db/TemplateDataStoreDao.java (81%) rename engine/{storage/src/org/apache/cloudstack/storage => api/src/org/apache/cloudstack/storage/datastore}/db/TemplateDataStoreVO.java (99%) rename engine/{storage/src/org/apache/cloudstack/storage => api/src/org/apache/cloudstack/storage/datastore}/db/VolumeDataStoreDao.java (81%) rename engine/{storage/src/org/apache/cloudstack/storage => api/src/org/apache/cloudstack/storage/datastore}/db/VolumeDataStoreVO.java (99%) rename engine/{api/src/org/apache/cloudstack/storage/datastore => storage/src/org/apache/cloudstack/storage}/db/DataStoreProviderDaoImpl.java (88%) rename engine/storage/src/org/apache/cloudstack/storage/{ => image}/db/SnapshotDataStoreDaoImpl.java (64%) rename engine/storage/src/org/apache/cloudstack/storage/{ => image}/db/TemplateDataStoreDaoImpl.java (70%) rename engine/storage/src/org/apache/cloudstack/storage/{ => image}/db/VolumeDataStoreDaoImpl.java (76%) rename engine/{api/src/org/apache/cloudstack/storage/datastore => storage/src/org/apache/cloudstack/storage/volume}/db/PrimaryDataStoreDetailsDaoImpl.java (92%) diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java similarity index 94% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 18841bc16e2..a81fa9c0bc1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.db; +package org.apache.cloudstack.storage.datastore.db; import com.cloud.utils.db.GenericDao; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java similarity index 97% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java index 3afddaa9c24..63ac9e4f3f9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java @@ -14,7 +14,7 @@ // 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.db; +package org.apache.cloudstack.storage.datastore.db; import org.apache.cloudstack.api.InternalIdentity; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java similarity index 92% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java index 98672904d54..033a818faa7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java @@ -14,7 +14,7 @@ // 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.db; +package org.apache.cloudstack.storage.datastore.db; import java.util.Map; @@ -24,5 +24,8 @@ import com.cloud.utils.db.GenericDao; public interface ImageStoreDetailsDao extends GenericDao { void update(long storeId, Map details); + Map getDetails(long storeId); + + void deleteDetails(long storeId); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java similarity index 98% rename from engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java index 36d05e56011..62c1be05eee 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreVO.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.db; +package org.apache.cloudstack.storage.datastore.db; import java.util.Date; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java similarity index 68% rename from engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index 8a62766fa8f..4d92fd3311d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -14,14 +14,22 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.datastore.db; +import java.util.List; + import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; + import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface SnapshotDataStoreDao extends GenericDao, StateDao { +public interface SnapshotDataStoreDao extends GenericDao, StateDao { + public List listByStoreId(long id); + + public List listLiveByStoreId(long id); + + public void deletePrimaryRecordsForStore(long id); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java similarity index 99% rename from engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index 527385f4be3..0f9c95ad8cf 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.datastore.db; import java.util.Date; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java similarity index 81% rename from engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index 2faf3c729c9..591b84c89f0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -14,9 +14,10 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.datastore.db; + +import java.util.List; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.utils.db.GenericDao; @@ -24,4 +25,9 @@ import com.cloud.utils.fsm.StateDao; public interface TemplateDataStoreDao extends GenericDao, StateDao { + public List listByStoreId(long id); + + public List listLiveByStoreId(long id); + + public void deletePrimaryRecordsForStore(long id); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java similarity index 99% rename from engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index af393a5221d..4e48437ec2a 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.datastore.db; import java.util.Date; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java similarity index 81% rename from engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java index e687d88082f..709097ea4a1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreDao.java @@ -14,9 +14,11 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.datastore.db; +import java.util.List; + import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.utils.db.GenericDao; @@ -24,4 +26,9 @@ import com.cloud.utils.fsm.StateDao; public interface VolumeDataStoreDao extends GenericDao, StateDao { + public List listByStoreId(long id); + + public List listLiveByStoreId(long id); + + public void deletePrimaryRecordsForStore(long id); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java similarity index 99% rename from engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java rename to engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index b27a4baa902..1fb61845fcc 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.datastore.db; import java.util.Date; 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 7ea68dc731f..9694a4cf703 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 @@ -29,11 +29,11 @@ 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.ImageStoreProvider; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; 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.db.ImageStoreDao; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.springframework.stereotype.Component; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 60c71f0ffa5..17f2b899777 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -32,9 +32,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; import com.cloud.storage.ImageStore; import com.cloud.storage.dao.VMTemplateDao; diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java similarity index 88% rename from engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java index ccb6b483253..fce716a08a6 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java @@ -16,8 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.datastore.db; +package org.apache.cloudstack.storage.db; +import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; +import org.apache.cloudstack.storage.datastore.db.DataStoreProviderVO; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index 30ebd1d1b83..eb264047cfa 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -23,10 +23,10 @@ import java.util.Map; import javax.inject.Inject; -import org.apache.cloudstack.storage.image.db.ImageStoreDao; -import org.apache.cloudstack.storage.image.db.ImageStoreDetailVO; -import org.apache.cloudstack.storage.image.db.ImageStoreDetailsDao; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.springframework.stereotype.Component; import com.cloud.storage.ImageStore; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 60d414c893d..2becada51a1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.storage.image.db; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java index e96d6fd93dc..8f711c686de 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java @@ -22,8 +22,11 @@ import java.util.Map; import javax.ejb.Local; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.springframework.stereotype.Component; +import com.cloud.host.DetailVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -70,4 +73,18 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase sc = storeSearch.create(); + sc.setParameters("store", storeId); + + List results = search(sc, null); + for (ImageStoreDetailVO result : results) { + remove(result.getId()); + } + + } + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java similarity index 64% rename from engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 1c291db1bd4..1fed7919a58 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -14,32 +14,48 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.image.db; import java.util.Date; +import java.util.List; import java.util.Map; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.StoragePoolHostVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; @Component -public class SnapshotDataStoreDaoImpl extends GenericDaoBase implements VolumeDataStoreDao { +public class SnapshotDataStoreDaoImpl extends GenericDaoBase implements SnapshotDataStoreDao { private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreDaoImpl.class); - private SearchBuilder updateStateSearch; + private SearchBuilder updateStateSearch; + private SearchBuilder storeSearch; + private SearchBuilder liveStoreSearch; + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); + storeSearch = createSearchBuilder(); + storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.done(); + + liveStoreSearch = createSearchBuilder(); + liveStoreSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + liveStoreSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + liveStoreSearch.done(); + updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -47,14 +63,15 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = updateStateSearch.create(); + SearchCriteria sc = updateStateSearch.create(); sc.setParameters("id", dataObj.getId()); sc.setParameters("state", currentState); sc.setParameters("updatedCount", dataObj.getUpdatedCount()); @@ -67,7 +84,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase listLiveByStoreId(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public void deletePrimaryRecordsForStore(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + Transaction txn = Transaction.currentTxn(); + txn.start(); + remove(sc); + txn.commit(); + } + + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java similarity index 70% rename from engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index c40b8ba0cd3..2066c5d7c6f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -14,8 +14,9 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.image.db; import java.util.Date; +import java.util.List; import java.util.Map; import javax.naming.ConfigurationException; @@ -23,12 +24,16 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; @@ -36,17 +41,30 @@ import com.cloud.utils.db.UpdateBuilder; public class TemplateDataStoreDaoImpl extends GenericDaoBase implements TemplateDataStoreDao { private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class); private SearchBuilder updateStateSearch; + private SearchBuilder storeSearch; + private SearchBuilder liveStoreSearch; + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); - updateStateSearch = this.createSearchBuilder(); + storeSearch = createSearchBuilder(); + storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.done(); + + liveStoreSearch = createSearchBuilder(); + liveStoreSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + liveStoreSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + liveStoreSearch.done(); + + updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); updateStateSearch.done(); return true; } + @Override public boolean updateState(State currentState, Event event, State nextState, TemplateDataStoreVO dataObj, Object data) { @@ -83,4 +101,27 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase 0; } + @Override + public List listByStoreId(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + return listIncludingRemovedBy(sc); + } + @Override + public List listLiveByStoreId(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public void deletePrimaryRecordsForStore(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + Transaction txn = Transaction.currentTxn(); + txn.start(); + remove(sc); + txn.commit(); + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java similarity index 76% rename from engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index 1f7b278d9bf..34de3f249b4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -14,8 +14,9 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.db; +package org.apache.cloudstack.storage.image.db; import java.util.Date; +import java.util.List; import java.util.Map; import javax.naming.ConfigurationException; @@ -23,12 +24,17 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; @@ -36,6 +42,9 @@ import com.cloud.utils.db.UpdateBuilder; public class VolumeDataStoreDaoImpl extends GenericDaoBase implements VolumeDataStoreDao { private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class); private SearchBuilder updateStateSearch; + private SearchBuilder storeSearch; + private SearchBuilder liveStoreSearch; + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); @@ -83,4 +92,27 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase 0; } + @Override + public List listByStoreId(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + return listIncludingRemovedBy(sc); + } + @Override + public List listLiveByStoreId(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public void deletePrimaryRecordsForStore(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + Transaction txn = Transaction.currentTxn(); + txn.start(); + remove(sc); + txn.commit(); + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java similarity index 92% rename from engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java rename to engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java index 59c488cf6d4..b0a387a0fbb 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java @@ -14,11 +14,14 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.storage.datastore.db; +package org.apache.cloudstack.storage.volume.db; import java.util.HashMap; import java.util.List; import java.util.Map; + +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDetailVO; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDetailsDao; import org.springframework.stereotype.Component; import com.cloud.utils.db.GenericDaoBase; diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java index fbd9909150a..922205a5ff8 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java @@ -29,10 +29,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageStoreDao; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java index 7d22df5006b..c3843560296 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -30,10 +30,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageStoreDao; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java index 8c61f036a16..fbe9f196a9f 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java @@ -24,10 +24,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageStoreDao; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import com.cloud.agent.api.StoragePoolInfo; diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java index 62dbfaebce8..799d4e0812c 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -29,10 +29,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; -import org.apache.cloudstack.storage.image.db.ImageStoreDao; -import org.apache.cloudstack.storage.image.db.ImageStoreVO; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 88b1a520dd6..c9f97be2a81 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -64,8 +64,17 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -78,6 +87,7 @@ import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.manager.AgentAttache; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; @@ -125,6 +135,7 @@ import com.cloud.org.Grouping; import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; +import com.cloud.resource.ResourceStateAdapter; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; import com.cloud.service.dao.ServiceOfferingDao; @@ -175,6 +186,7 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.DiskProfile; import com.cloud.vm.UserVmManager; import com.cloud.vm.VMInstanceVO; @@ -243,6 +255,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected PrimaryDataStoreDao _storagePoolDao = null; @Inject + protected ImageStoreDao _imageStoreDao = null; + @Inject + protected ImageStoreDetailsDao _imageStoreDetailsDao = null; + @Inject + protected SnapshotDataStoreDao _snapshotStoreDao = null; + @Inject + protected TemplateDataStoreDao _templateStoreDao = null; + @Inject + protected VolumeDataStoreDao _volumeStoreDao = null; + @Inject protected CapacityDao _capacityDao; @Inject protected CapacityManager _capacityMgr; @@ -1949,10 +1971,44 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); } + @Override public boolean deleteImageStore(DeleteImageStoreCmd cmd) { - // TODO Auto-generated method stub - return false; + long storeId = cmd.getId(); + User caller = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); + // Verify that image store exists + ImageStoreVO store = _imageStoreDao.findById(storeId); + if (store == null) { + throw new InvalidParameterValueException("Image store with id " + storeId + " doesn't exist"); + } + _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId()); + + // Verify that there are no live snapshot, template, volume on the image store to be deleted + List snapshots = _snapshotStoreDao.listLiveByStoreId(storeId); + if ( snapshots != null && snapshots.size() > 0 ){ + throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!"); + } + List volumes = _volumeStoreDao.listLiveByStoreId(storeId); + if ( volumes != null && volumes.size() > 0 ){ + throw new CloudRuntimeException("Cannot delete image store with active volumes backup!"); + } + List templates = _templateStoreDao.listLiveByStoreId(storeId); + if ( templates != null && templates.size() > 0 ){ + throw new CloudRuntimeException("Cannot delete image store with active templates backup!"); + } + + // ready to delete + Transaction txn = Transaction.currentTxn(); + txn.start(); + // first delete from image_store_details table, we need to do that since we are not actually deleting record from main + // image_data_store table, so delete cascade will not work + _imageStoreDetailsDao.deleteDetails(storeId); + _snapshotStoreDao.deletePrimaryRecordsForStore(storeId); + _volumeStoreDao.deletePrimaryRecordsForStore(storeId); + _templateStoreDao.deletePrimaryRecordsForStore(storeId); + _imageStoreDao.remove(storeId); + txn.commit(); + return true; } From 9be9902ed5ea8e1e3f459b783b485f4ecbc89da1 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 9 Apr 2013 14:49:09 -0700 Subject: [PATCH 011/303] Fix applicationContext.xml to properly load all new refactored image store related classes, also add enableImageStore api. --- api/src/com/cloud/storage/StorageService.java | 2 + .../admin/storage/EnableImageStoreCmd.java | 89 +++++++++++++++++++ client/pom.xml | 15 ++++ client/tomcatconf/applicationContext.xml.in | 17 ++-- .../storage/datastore/db/ImageStoreDao.java | 2 + .../storage/image/db/ImageStoreDaoImpl.java | 49 +++++++++- .../image/db/SnapshotDataStoreDaoImpl.java | 6 +- .../image/db/TemplateDataStoreDaoImpl.java | 6 +- .../image/db/VolumeDataStoreDaoImpl.java | 11 ++- .../com/cloud/storage/StorageManagerImpl.java | 37 ++++++++ 10 files changed, 216 insertions(+), 18 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index ee1a9565be4..665abcbfc94 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint 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; +import org.apache.cloudstack.api.command.admin.storage.EnableImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; import com.cloud.exception.DiscoveryException; @@ -91,4 +92,5 @@ public interface StorageService{ ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; + ImageStore enableImageStore(EnableImageStoreCmd cmd); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java new file mode 100644 index 00000000000..7586fa9be18 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java @@ -0,0 +1,89 @@ +// 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 javax.inject.Inject; + +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.response.AccountResponse; +import org.apache.cloudstack.api.response.DomainResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.cloudstack.region.RegionService; +import org.apache.log4j.Logger; + +import com.cloud.storage.ImageStore; +import com.cloud.user.Account; + +@APICommand(name = "enableImageStore", description="Enable an image store", responseObject=ImageStoreResponse.class) +public class EnableImageStoreCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(EnableImageStoreCmd.class.getName()); + private static final String s_name = "enableimagestoreresponse"; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=ImageStoreResponse.class, + description="Image Store id") + private Long id; + + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="Enables specified image store.") + private String storeName; + + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getId() { + return id; + } + + public String getStoreName() { + return storeName; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public String getCommandName() { + return s_name; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + @Override + public void execute(){ + ImageStore result = _storageService.enableImageStore(this); + if (result != null){ + ImageStoreResponse response = _responseGenerator.createImageStoreResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable image store"); + } + } +} diff --git a/client/pom.xml b/client/pom.xml index 9323d0fb20f..39f1cb0d1a6 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -224,6 +224,21 @@ cloud-plugin-storage-volume-default ${project.version} + + org.apache.cloudstack + cloud-plugin-storage-image-default + ${project.version} + + + org.apache.cloudstack + cloud-plugin-storage-image-s3 + ${project.version} + + + org.apache.cloudstack + cloud-plugin-storage-image-swift + ${project.version} + org.apache.cloudstack cloud-plugin-syslog-alerts diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 7bf45a24715..d8bb30abbc0 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -190,7 +190,7 @@ - + @@ -223,8 +223,12 @@ - - + + + + + + @@ -270,7 +274,7 @@ - + @@ -713,7 +717,6 @@ - @@ -732,6 +735,7 @@ + @@ -739,8 +743,7 @@ - - + diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index a81fa9c0bc1..1c307664a75 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -22,4 +22,6 @@ import com.cloud.utils.db.GenericDao; public interface ImageStoreDao extends GenericDao { public ImageStoreVO findByName(String name); + + public ImageStoreVO findEnabledStore(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 2becada51a1..8aa5079e46b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -18,11 +18,22 @@ */ package org.apache.cloudstack.storage.image.db; +import java.util.Map; + +import javax.naming.ConfigurationException; + import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.ImageStore; +import com.cloud.user.AccountVO; +import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.db.SearchCriteria.Op; @@ -30,11 +41,41 @@ import com.cloud.utils.db.SearchCriteria.Op; @Component public class ImageStoreDaoImpl extends GenericDaoBase implements ImageStoreDao { + private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class); + private SearchBuilder nameSearch; + private SearchBuilder enableSearch; + + @Override - public ImageStoreVO findByName(String name) { - SearchCriteriaService sc = SearchCriteria2.create(ImageStoreVO.class); - sc.addAnd(sc.getEntity().getName(), Op.EQ, name); - return sc.find(); + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + + nameSearch = createSearchBuilder(); + nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ); + nameSearch.done(); + + + enableSearch = createSearchBuilder(); + enableSearch.and("state", enableSearch.entity().getState(), SearchCriteria.Op.EQ); + enableSearch.done(); + + return true; } + @Override + public ImageStoreVO findByName(String name) { + SearchCriteria sc = nameSearch.create(); + sc.setParameters("name", name); + return findOneBy(sc); + } + + @Override + public ImageStoreVO findEnabledStore() { + SearchCriteria sc = nameSearch.create(); + sc.setParameters("state", ImageStore.State.Enabled); // only one image store is enabled at one time. + return findOneBy(sc); + } + + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 1fed7919a58..a1c4871caa3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -52,8 +52,8 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase listLiveByStoreId(long id) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = liveStoreSearch.create(); sc.setParameters("store_id", id); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index 2066c5d7c6f..d7019d29924 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -53,8 +53,8 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listLiveByStoreId(long id) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = liveStoreSearch.create(); sc.setParameters("store_id", id); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index 34de3f249b4..b8127ee3361 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -49,6 +49,15 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { super.configure(name, params); + storeSearch = createSearchBuilder(); + storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.done(); + + liveStoreSearch = createSearchBuilder(); + liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + liveStoreSearch.done(); + updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -100,7 +109,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase listLiveByStoreId(long id) { - SearchCriteria sc = storeSearch.create(); + SearchCriteria sc = liveStoreSearch.create(); sc.setParameters("store_id", id); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index c9f97be2a81..162df1a1cd3 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint 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; +import org.apache.cloudstack.api.command.admin.storage.EnableImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -165,6 +166,7 @@ import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.AccountVO; import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; @@ -2011,5 +2013,40 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return true; } + @Override + public ImageStore enableImageStore(EnableImageStoreCmd cmd) { + Long storeId = cmd.getId(); + String storeName = cmd.getStoreName(); + + ImageStore store = null; + if ( storeId != null ){ + store = _imageStoreDao.findById(storeId); + } else if ( storeName != null ){ + store = _imageStoreDao.findByName(storeName); + } else { + throw new InvalidParameterValueException("Either image store id or name has to be specified!"); + } + + if (store == null) { + throw new InvalidParameterValueException("Unable to find image store by id: " + storeId + " OR by name: " + storeName); + } + // disable currently active store + ImageStoreVO activeStore = _imageStoreDao.findEnabledStore(); + ImageStoreVO activeStoreForUpdate = _imageStoreDao.createForUpdate(); + activeStoreForUpdate.setState(ImageStore.State.Disabled); + if ( !_imageStoreDao.update(activeStore.getId(), activeStoreForUpdate)){ + throw new CloudRuntimeException("Failed to disable current active image store " + activeStore.getName()); + } + + ImageStoreVO storeForUpdate = _imageStoreDao.createForUpdate(); + storeForUpdate.setState(ImageStore.State.Enabled); + if (_imageStoreDao.update(store.getId(), storeForUpdate)){ + return _imageStoreDao.findById(store.getId()); + } + else{ + throw new CloudRuntimeException("Failed to enable image store by id: " + storeId + " OR by name: " + storeName); + } + } + } From 2a177de2bc07a1900bcbde8b57961d244f387daf Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 9 Apr 2013 14:59:07 -0700 Subject: [PATCH 012/303] Remove unused DataStoreProviderDao since provider does not has its own db table. --- client/tomcatconf/applicationContext.xml.in | 1 - .../datastore/db/DataStoreProviderDao.java | 25 -------- .../datastore/db/DataStoreProviderVO.java | 60 ------------------- .../DataStoreProviderManagerImpl.java | 3 - .../storage/db/DataStoreProviderDaoImpl.java | 40 ------------- .../PrimaryDataStoreProviderManagerImpl.java | 7 +-- 6 files changed, 2 insertions(+), 134 deletions(-) delete mode 100644 engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java delete mode 100644 engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index d8bb30abbc0..206afd3c8f3 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -190,7 +190,6 @@ - diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java deleted file mode 100644 index dca83ce0b8a..00000000000 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderDao.java +++ /dev/null @@ -1,25 +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.datastore.db; - -import com.cloud.utils.db.GenericDao; - -public interface DataStoreProviderDao extends GenericDao { - public DataStoreProviderVO findByName(String name); -} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java deleted file mode 100644 index dcdafddb175..00000000000 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/DataStoreProviderVO.java +++ /dev/null @@ -1,60 +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.datastore.db; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.TableGenerator; - -@Entity -@Table(name = "data_store_provider") -public class DataStoreProviderVO { - @Id - @TableGenerator(name = "data_store_provider_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "data_store_provider_seq", allocationSize = 1) - @Column(name = "id", updatable = false, nullable = false) - private long id; - - @Column(name = "name", nullable = false) - private String name; - - @Column(name = "uuid", nullable = false) - private String uuid; - - public long getId() { - return id; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public String getUuid() { - return this.uuid; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index 1bfc5ff02a6..624c7c7c7d0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -36,7 +36,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -50,8 +49,6 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto .getLogger(DataStoreProviderManagerImpl.class); @Inject List providers; - @Inject - DataStoreProviderDao providerDao; protected Map providerMap = new HashMap(); @Inject PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java deleted file mode 100644 index fce716a08a6..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/db/DataStoreProviderDaoImpl.java +++ /dev/null @@ -1,40 +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.db; - -import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; -import org.apache.cloudstack.storage.datastore.db.DataStoreProviderVO; -import org.springframework.stereotype.Component; - -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.SearchCriteria.Op; - -@Component -class DataStoreProviderDaoImpl extends GenericDaoBase implements DataStoreProviderDao { - - @Override - public DataStoreProviderVO findByName(String name) { - SearchCriteriaService sc = SearchCriteria2.create(DataStoreProviderVO.class); - sc.addAnd(sc.getEntity().getName(), Op.EQ, name); - return sc.find(); - } - -} \ No newline at end of file diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java index 7a5d3224444..8d688c00b41 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/manager/PrimaryDataStoreProviderManagerImpl.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver import org.apache.cloudstack.storage.datastore.PrimaryDataStoreImpl; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.datastore.db.DataStoreProviderDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.springframework.stereotype.Component; @@ -40,8 +39,6 @@ import com.cloud.storage.StorageManager; @Component public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProviderManager { - @Inject - DataStoreProviderDao dataStoreProviderDao; @Inject DataStoreProviderManager providerManager; @Inject @@ -53,7 +50,7 @@ public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProv public void config() { driverMaps = new HashMap(); } - + @Override public PrimaryDataStore getPrimaryDataStore(long dataStoreId) { StoragePoolVO dataStoreVO = dataStoreDao.findById(dataStoreId); @@ -62,7 +59,7 @@ public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProv PrimaryDataStoreImpl dataStore = PrimaryDataStoreImpl.createDataStore(dataStoreVO, driverMaps.get(provider.getName()), provider); return dataStore; } - + @Override public boolean registerDriver(String providerName, PrimaryDataStoreDriver driver) { if (driverMaps.get(providerName) != null) { From b2d5535bbaa68fea3ecd76846a33ff660a4889d7 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 9 Apr 2013 15:38:33 -0700 Subject: [PATCH 013/303] Remove State from image_store db table, and removed enableImageStore api. --- api/src/com/cloud/storage/ImageStore.java | 8 -- api/src/com/cloud/storage/StorageService.java | 2 - .../admin/host/AddSecondaryStorageCmd.java | 30 ------- .../admin/storage/AddImageStoreCmd.java | 2 +- .../admin/storage/DeleteImageStoreCmd.java | 2 +- .../admin/storage/EnableImageStoreCmd.java | 89 ------------------- .../admin/storage/ListImageStoresCmd.java | 9 +- .../api/response/ImageStoreResponse.java | 13 --- .../storage/datastore/db/ImageStoreDao.java | 1 - .../storage/datastore/db/ImageStoreVO.java | 12 --- .../storage/image/store/ImageStoreImpl.java | 5 -- .../image/datastore/ImageStoreHelper.java | 2 - .../storage/image/db/ImageStoreDaoImpl.java | 14 --- .../com/cloud/api/query/QueryManagerImpl.java | 13 --- .../api/query/dao/ImageStoreJoinDaoImpl.java | 1 - .../cloud/api/query/vo/ImageStoreJoinVO.java | 12 --- .../com/cloud/storage/StorageManagerImpl.java | 36 -------- setup/db/db/schema-410to420.sql | 2 - 18 files changed, 3 insertions(+), 250 deletions(-) delete mode 100644 api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java diff --git a/api/src/com/cloud/storage/ImageStore.java b/api/src/com/cloud/storage/ImageStore.java index 54d22d10f3f..d2a72a21fa6 100644 --- a/api/src/com/cloud/storage/ImageStore.java +++ b/api/src/com/cloud/storage/ImageStore.java @@ -21,10 +21,6 @@ import org.apache.cloudstack.api.InternalIdentity; public interface ImageStore extends Identity, InternalIdentity { - public enum State { - Disabled, Enabled, Deactivated; - } - /** * @return name of the object store. @@ -36,10 +32,6 @@ public interface ImageStore extends Identity, InternalIdentity { */ Long getDataCenterId(); - /** - * @return image store state. - */ - State getState(); /** * @return object store provider name diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index 665abcbfc94..ee1a9565be4 100644 --- a/api/src/com/cloud/storage/StorageService.java +++ b/api/src/com/cloud/storage/StorageService.java @@ -23,7 +23,6 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint 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; -import org.apache.cloudstack.api.command.admin.storage.EnableImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; import com.cloud.exception.DiscoveryException; @@ -92,5 +91,4 @@ public interface StorageService{ ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException; - ImageStore enableImageStore(EnableImageStoreCmd cmd); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java index 94aaa5fcc25..3f243703825 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java @@ -50,20 +50,6 @@ public class AddSecondaryStorageCmd extends BaseCmd { description="the Zone ID for the secondary storage") private Long zoneId; - @Parameter(name=ApiConstants.REGION_ID, type=CommandType.UUID, entityType=RegionResponse.class, - description="the Region ID for the secondary storage") - private Long regionId; - - @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the secondary storage data store") - private Map details; - - @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, - required=false, description="the scope of the secondary storage data store: zone or region or global") - private String scope; - - @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, - required=false, description="the secondary storage store provider name") - private String imageProviderName; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -77,22 +63,6 @@ public class AddSecondaryStorageCmd extends BaseCmd { return zoneId; } - public Long getRegionId() { - return regionId; - } - - public Map getDetails() { - return details; - } - - public String getScope() { - return this.scope; - } - - public String getImageProviderName() { - return this.imageProviderName; - } - ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index 511283f6626..c5a8c4a66b8 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -32,7 +32,7 @@ import com.cloud.exception.DiscoveryException; import com.cloud.storage.ImageStore; import com.cloud.user.Account; -@APICommand(name = "addImageStore", description="Adds backup image store.", responseObject=ImageStoreResponse.class) +@APICommand(name = "addImageStore", description="Adds backup image store.", responseObject=ImageStoreResponse.class, since = "4.2.0") public class AddImageStoreCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(AddImageStoreCmd.class.getName()); private static final String s_name = "addimagestoreresponse"; diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java index 34a4ae076cb..20ddc8b6fec 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/DeleteImageStoreCmd.java @@ -29,7 +29,7 @@ import org.apache.log4j.Logger; import com.cloud.user.Account; -@APICommand(name = "deleteImageStore", description = "Deletes an image store .", responseObject = SuccessResponse.class) +@APICommand(name = "deleteImageStore", description = "Deletes an image store .", responseObject = SuccessResponse.class, since = "4.2.0") public class DeleteImageStoreCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(DeleteImageStoreCmd.class.getName()); diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java deleted file mode 100644 index 7586fa9be18..00000000000 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/EnableImageStoreCmd.java +++ /dev/null @@ -1,89 +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.api.command.admin.storage; - -import javax.inject.Inject; - -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.response.AccountResponse; -import org.apache.cloudstack.api.response.DomainResponse; -import org.apache.cloudstack.api.response.ImageStoreResponse; -import org.apache.cloudstack.region.RegionService; -import org.apache.log4j.Logger; - -import com.cloud.storage.ImageStore; -import com.cloud.user.Account; - -@APICommand(name = "enableImageStore", description="Enable an image store", responseObject=ImageStoreResponse.class) -public class EnableImageStoreCmd extends BaseCmd { - public static final Logger s_logger = Logger.getLogger(EnableImageStoreCmd.class.getName()); - private static final String s_name = "enableimagestoreresponse"; - - ///////////////////////////////////////////////////// - //////////////// API parameters ///////////////////// - ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=ImageStoreResponse.class, - description="Image Store id") - private Long id; - - @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="Enables specified image store.") - private String storeName; - - - ///////////////////////////////////////////////////// - /////////////////// Accessors /////////////////////// - ///////////////////////////////////////////////////// - - public Long getId() { - return id; - } - - public String getStoreName() { - return storeName; - } - - ///////////////////////////////////////////////////// - /////////////// API Implementation/////////////////// - ///////////////////////////////////////////////////// - - @Override - public String getCommandName() { - return s_name; - } - - @Override - public long getEntityOwnerId() { - return Account.ACCOUNT_ID_SYSTEM; - } - - @Override - public void execute(){ - ImageStore result = _storageService.enableImageStore(this); - if (result != null){ - ImageStoreResponse response = _responseGenerator.createImageStoreResponse(result); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable image store"); - } - } -} diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java index 4dbe9006ee9..499cc041620 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java @@ -30,7 +30,7 @@ import org.apache.log4j.Logger; import com.cloud.async.AsyncJob; -@APICommand(name = "listImageStores", description="Lists image stores.", responseObject=ImageStoreResponse.class) +@APICommand(name = "listImageStores", description="Lists image stores.", responseObject=ImageStoreResponse.class, since = "4.2.0") public class ListImageStoresCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListImageStoresCmd.class.getName()); @@ -43,9 +43,6 @@ public class ListImageStoresCmd extends BaseListCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the image store") private String storeName; - @Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="the image store state") - private String state; - @Parameter(name=ApiConstants.PROTOCOL, type=CommandType.STRING, description="the image store protocol") private String protocol; @@ -74,10 +71,6 @@ public class ListImageStoresCmd extends BaseListCmd { return storeName; } - public String getState() { - return state; - } - public String getProtocol() { return protocol; } diff --git a/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java b/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java index 21dc635a09c..04a375f467c 100644 --- a/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ImageStoreResponse.java @@ -39,10 +39,6 @@ public class ImageStoreResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the Zone name of the image store") private String zoneName; - @SerializedName("state") @Param(description="the state of the image store") - private ImageStore.State state; - - @SerializedName("name") @Param(description="the name of the image store") private String name; @@ -95,15 +91,6 @@ public class ImageStoreResponse extends BaseResponse { this.zoneName = zoneName; } - - public ImageStore.State getState() { - return state; - } - - public void setState(ImageStore.State state) { - this.state = state; - } - public String getName() { return name; } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 1c307664a75..595e498ebf0 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -23,5 +23,4 @@ import com.cloud.utils.db.GenericDao; public interface ImageStoreDao extends GenericDao { public ImageStoreVO findByName(String name); - public ImageStoreVO findEnabledStore(); } 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 62c1be05eee..7f950362fd8 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 @@ -60,10 +60,6 @@ public class ImageStoreVO implements ImageStore { @Column(name = "data_center_id") private long dcId; - @Column(name = "state") - @Enumerated(value = EnumType.STRING) - private State state; - @Column(name = "scope") @Enumerated(value = EnumType.STRING) private ScopeType scope; @@ -150,14 +146,6 @@ public class ImageStoreVO implements ImageStore { this.removed = removed; } - public State getState() { - return state; - } - - public void setState(State state) { - this.state = state; - } - } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 17f2b899777..90290d865f7 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -36,7 +36,6 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; -import com.cloud.storage.ImageStore; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.storage.encoding.EncodingType; @@ -154,10 +153,6 @@ public class ImageStoreImpl implements ImageStoreEntity { return imageDataStoreVO.getDataCenterId(); } - @Override - public ImageStore.State getState() { - return imageDataStoreVO.getState(); - } @Override public String getProviderName() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index eb264047cfa..33fda486c36 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -52,7 +52,6 @@ public class ImageStoreHelper { store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); - store.setState(ImageStore.State.Disabled); store = imageStoreDao.persist(store); return store; } @@ -69,7 +68,6 @@ public class ImageStoreHelper { store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); - store.setState(ImageStore.State.Disabled); store = imageStoreDao.persist(store); // persist details diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 8aa5079e46b..605ac5bd5c6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -43,7 +43,6 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class); private SearchBuilder nameSearch; - private SearchBuilder enableSearch; @Override @@ -54,11 +53,6 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ); nameSearch.done(); - - enableSearch = createSearchBuilder(); - enableSearch.and("state", enableSearch.entity().getState(), SearchCriteria.Op.EQ); - enableSearch.done(); - return true; } @@ -69,13 +63,5 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem return findOneBy(sc); } - @Override - public ImageStoreVO findEnabledStore() { - SearchCriteria sc = nameSearch.create(); - sc.setParameters("state", ImageStore.State.Enabled); // only one image store is enabled at one time. - return findOneBy(sc); - } - - } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index daf49cbddac..4b4c86e2f4e 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -1931,15 +1931,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Object name = cmd.getStoreName(); String provider = cmd.getProvider(); String protocol = cmd.getProtocol(); - ImageStore.State state = null; - String stateStr = cmd.getState(); - if (stateStr != null) { - try { - state = Enum.valueOf(ImageStore.State.class, stateStr.toUpperCase()); - } catch (Exception e) { - throw new InvalidParameterValueException("invalid state" + stateStr); - } - } Object keyword = cmd.getKeyword(); Long startIndex = cmd.getStartIndex(); Long pageSize = cmd.getPageSizeVal(); @@ -1953,7 +1944,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("name", sb.entity().getName(), SearchCriteria.Op.EQ); sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ); - sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ); sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ); @@ -1982,9 +1972,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (provider != null) { sc.setParameters("provider", provider); } - if (state != null) { - sc.setParameters("state", state); - } if (protocol != null) { sc.setParameters("protocol", protocol); } diff --git a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java index b2fa0c20529..72446f493bb 100644 --- a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java @@ -76,7 +76,6 @@ public class ImageStoreJoinDaoImpl extends GenericDaoBase 0 ){ diff --git a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java index 62c4a8f1a13..ce56860d98f 100644 --- a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java @@ -68,9 +68,6 @@ public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Id @Column(name="data_center_name") private String zoneName; - @Column(name="state") - private ImageStore.State state; - @Column(name="detail_name") private String detailName; @@ -159,15 +156,6 @@ public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Id this.scope = scope; } - - public ImageStore.State getState() { - return state; - } - - public void setState(ImageStore.State state) { - this.state = state; - } - public void setName(String name) { this.name = name; } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 162df1a1cd3..ca4c636ed74 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -45,7 +45,6 @@ import org.apache.cloudstack.api.command.admin.storage.CancelPrimaryStorageMaint 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; -import org.apache.cloudstack.api.command.admin.storage.EnableImageStoreCmd; import org.apache.cloudstack.api.command.admin.storage.UpdateStoragePoolCmd; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -2013,40 +2012,5 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return true; } - @Override - public ImageStore enableImageStore(EnableImageStoreCmd cmd) { - Long storeId = cmd.getId(); - String storeName = cmd.getStoreName(); - - ImageStore store = null; - if ( storeId != null ){ - store = _imageStoreDao.findById(storeId); - } else if ( storeName != null ){ - store = _imageStoreDao.findByName(storeName); - } else { - throw new InvalidParameterValueException("Either image store id or name has to be specified!"); - } - - if (store == null) { - throw new InvalidParameterValueException("Unable to find image store by id: " + storeId + " OR by name: " + storeName); - } - // disable currently active store - ImageStoreVO activeStore = _imageStoreDao.findEnabledStore(); - ImageStoreVO activeStoreForUpdate = _imageStoreDao.createForUpdate(); - activeStoreForUpdate.setState(ImageStore.State.Disabled); - if ( !_imageStoreDao.update(activeStore.getId(), activeStoreForUpdate)){ - throw new CloudRuntimeException("Failed to disable current active image store " + activeStore.getName()); - } - - ImageStoreVO storeForUpdate = _imageStoreDao.createForUpdate(); - storeForUpdate.setState(ImageStore.State.Enabled); - if (_imageStoreDao.update(store.getId(), storeForUpdate)){ - return _imageStoreDao.findById(store.getId()); - } - else{ - throw new CloudRuntimeException("Failed to enable image store by id: " + storeId + " OR by name: " + storeName); - } - } - } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 38bad7ab9de..e8739fc71c4 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -77,7 +77,6 @@ CREATE TABLE `cloud`.`image_store` ( `data_center_id` bigint unsigned COMMENT 'datacenter id of data store', `scope` varchar(255) COMMENT 'scope of data store', `uuid` varchar(255) COMMENT 'uuid of data store', - `state` varchar(30) COMMENT 'state of data store', `created` datetime COMMENT 'date the image store first signed on', `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY(`id`) @@ -103,7 +102,6 @@ CREATE VIEW `cloud`.`image_store_view` AS image_store.protocol, image_store.url, image_store.scope, - image_store.state, data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, From 3897590bb16bd68f3e2e3f2d421f19236697ff11 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 9 Apr 2013 16:36:02 -0700 Subject: [PATCH 014/303] Add check in addImageStoreCmd to guarantee our assumption of homogeneous image stores. --- .../admin/storage/AddImageStoreCmd.java | 14 +++----- .../api/storage/DataStoreManager.java | 3 +- .../api/storage/DataStoreProvider.java | 5 ++- .../api/storage/ImageStoreProvider.java | 3 ++ .../storage/datastore/db/ImageStoreDao.java | 6 ++++ .../ImageStoreProviderManagerImpl.java | 29 ++++++++++++++-- .../strategy/AncientSnapshotStrategy.java | 2 +- .../datastore/DataStoreManagerImpl.java | 12 +++++-- .../DataStoreProviderManagerImpl.java | 6 ++-- .../datastore/ImageStoreProviderManager.java | 5 ++- .../storage/image/db/ImageStoreDaoImpl.java | 34 +++++++++++++++---- .../CloudStackImageStoreProviderImpl.java | 11 +++++- .../provider/S3ImageStoreProviderImpl.java | 10 +++++- .../SampleImageStoreProviderImpl.java | 10 ++++++ .../provider/SwiftImageStoreProviderImpl.java | 10 +++++- .../com/cloud/storage/StorageManagerImpl.java | 28 +++++++++------ .../cloud/template/TemplateManagerImpl.java | 4 +-- 17 files changed, 147 insertions(+), 45 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index c5a8c4a66b8..7221f4ee90f 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -48,17 +48,15 @@ public class AddImageStoreCmd extends BaseCmd { description="the Zone ID for the image store") private Long zoneId; + @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, + required=true, description="the image store provider name") + private String providerName; + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store") private Map details; - @Parameter(name=ApiConstants.SCOPE, type=CommandType.STRING, - required=false, description="the scope of the image store: zone or region") - private String scope; - @Parameter(name=ApiConstants.PROVIDER, type=CommandType.STRING, - required=false, description="the image store provider name") - private String providerName; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -76,10 +74,6 @@ public class AddImageStoreCmd extends BaseCmd { return details; } - public String getScope() { - return this.scope; - } - public String getProviderName() { return this.providerName; } 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 15e49e133fb..f940e8e9803 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 @@ -26,6 +26,7 @@ public interface DataStoreManager { public DataStore getDataStore(long storeId, DataStoreRole role); public DataStore getPrimaryDataStore(long storeId); public DataStore getDataStore(String uuid, DataStoreRole role); - public List getImageStores(Scope scope); + public List getImageStoresByScope(Scope scope); + public List getImageStoresByProvider(String provider); public DataStore registerDataStore(Map params, String providerUuid); } 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 115a52f92ac..083c7d39b67 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 @@ -22,6 +22,8 @@ import java.util.Map; import java.util.Set; + + public interface DataStoreProvider { public static enum DataStoreProviderType { PRIMARY, @@ -33,5 +35,6 @@ public interface DataStoreProvider { public String getName(); public boolean configure(Map params); public Set getTypes(); - + + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index 9a1f69f3a5b..9b4b937b18a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java @@ -18,7 +18,10 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.ScopeType; + public interface ImageStoreProvider extends DataStoreProvider { + public boolean isScopeSupported(ScopeType scope); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 595e498ebf0..fbd09884d1f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -18,9 +18,15 @@ */ package org.apache.cloudstack.storage.datastore.db; +import java.util.List; + + +import com.cloud.storage.ScopeType; import com.cloud.utils.db.GenericDao; public interface ImageStoreDao extends GenericDao { public ImageStoreVO findByName(String name); + public List findByProvider(String provider); + public List findByScope(ScopeType scope); } 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 9694a4cf703..642821f77b5 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 @@ -29,6 +29,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.ImageStoreProvider; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; @@ -53,13 +54,13 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager public void config() { driverMaps = new HashMap(); } - + @Override public ImageStoreEntity getImageStore(long dataStoreId) { ImageStoreVO dataStore = dataStoreDao.findById(dataStoreId); String providerName = dataStore.getProviderName(); ImageStoreProvider provider = (ImageStoreProvider)providerManager.getDataStoreProvider(providerName); - ImageStoreEntity imgStore = ImageStoreImpl.getDataStore(dataStore, + ImageStoreEntity imgStore = ImageStoreImpl.getDataStore(dataStore, driverMaps.get(provider.getName()), provider ); // TODO Auto-generated method stub @@ -82,7 +83,7 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager } @Override - public List getList() { + public List listImageStores() { List stores = dataStoreDao.listAll(); List imageStores = new ArrayList(); for (ImageStoreVO store : stores) { @@ -91,4 +92,26 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager return imageStores; } + @Override + public List listImageStoresByScope(Scope scope) { + List stores = dataStoreDao.findByScope(scope.getScopeType()); + List imageStores = new ArrayList(); + for (ImageStoreVO store : stores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } + + @Override + public List listImageStoreByProvider(String provider) { + List stores = dataStoreDao.findByProvider(provider); + List imageStores = new ArrayList(); + for (ImageStoreVO store : stores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } + + + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java index 9e666d21515..3863481fb90 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java @@ -406,7 +406,7 @@ public class AncientSnapshotStrategy implements SnapshotStrategy { snapObj.processEvent(Snapshot.Event.BackupToSecondary); ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); - List stores = this.dataStoreMgr.getImageStores(scope); + List stores = this.dataStoreMgr.getImageStoresByScope(scope); if (stores.size() != 1) { throw new CloudRuntimeException("find out more than one image stores"); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 8c22767377a..8f8d3c92c52 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -62,10 +62,18 @@ public class DataStoreManagerImpl implements DataStoreManager { } throw new CloudRuntimeException("un recognized type" + role); } + @Override - public List getImageStores(Scope scope) { - return imageDataStoreMgr.getList(); + public List getImageStoresByScope(Scope scope) { + return imageDataStoreMgr.listImageStoresByScope(scope); } + + + @Override + public List getImageStoresByProvider(String provider) { + return imageDataStoreMgr.listImageStoreByProvider(provider); + } + @Override public DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index 624c7c7c7d0..b7ed53dfcf6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -65,7 +65,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return null; } - public List getPrimayrDataStoreProviders() { + public List getPrimaryDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { if (provider instanceof PrimaryDataStoreProvider) { @@ -139,7 +139,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Override public DataStoreProvider getDefaultImageDataStoreProvider() { - return this.getDataStoreProvider("cloudstack image store provider"); + return this.getDataStoreProvider("CloudStack ImageStore Provider"); } @Override @@ -148,7 +148,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto throw new InvalidParameterValueException("Invalid parameter, need to specify type: either primary or image"); } if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.PRIMARY.toString())) { - return this.getPrimayrDataStoreProviders(); + return this.getPrimaryDataStoreProviders(); } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.IMAGE.toString())) { return this.getImageDataStoreProviders(); } else { diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index d9a733d300f..bb5e20fdea0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -21,11 +21,14 @@ package org.apache.cloudstack.storage.image.datastore; import java.util.List; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.storage.image.ImageStoreDriver; public interface ImageStoreProviderManager { ImageStoreEntity getImageStore(long dataStoreId); ImageStoreEntity getImageStore(String uuid); - List getList(); + List listImageStores(); + List listImageStoresByScope(Scope scope); + List listImageStoreByProvider(String provider); boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 605ac5bd5c6..ab41a4b0deb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -18,31 +18,29 @@ */ package org.apache.cloudstack.storage.image.db; +import java.util.List; import java.util.Map; import javax.naming.ConfigurationException; + import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; -import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.storage.ImageStore; -import com.cloud.user.AccountVO; -import com.cloud.utils.db.DB; +import com.cloud.storage.ScopeType; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.SearchCriteria.Op; @Component public class ImageStoreDaoImpl extends GenericDaoBase implements ImageStoreDao { private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class); private SearchBuilder nameSearch; + private SearchBuilder providerSearch; + private SearchBuilder scopeSearch; @Override @@ -53,6 +51,14 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ); nameSearch.done(); + providerSearch = createSearchBuilder(); + providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ); + providerSearch.done(); + + scopeSearch = createSearchBuilder(); + scopeSearch.and("scope", scopeSearch.entity().getScope(), SearchCriteria.Op.EQ); + scopeSearch.done(); + return true; } @@ -63,5 +69,19 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem return findOneBy(sc); } + @Override + public List findByProvider(String provider) { + SearchCriteria sc = providerSearch.create(); + sc.setParameters("providerName", provider); + return listBy(sc); + } + + @Override + public List findByScope(ScopeType scope) { + SearchCriteria sc = scopeSearch.create(); + sc.setParameters("scope", scope); + return listBy(sc); + } + } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index 058dd27a039..e025cf4de4a 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -35,12 +35,13 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.springframework.stereotype.Component; +import com.cloud.storage.ScopeType; import com.cloud.utils.component.ComponentContext; @Component public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { - private final String providerName = "cloudstack image store provider"; + private final String providerName = "CloudStack ImageStore Provider"; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject @@ -85,4 +86,12 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { return types; } + @Override + public boolean isScopeSupported(ScopeType scope) { + if ( scope == ScopeType.ZONE) + return true; + return false; + } + + } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java index 820882dd75a..ba27d617838 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java @@ -44,7 +44,7 @@ import com.cloud.utils.component.ComponentContext; @Component public class S3ImageStoreProviderImpl implements ImageStoreProvider { - private final String providerName = "S3 image store provider"; + private final String providerName = "S3"; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject @@ -87,4 +87,12 @@ public class S3ImageStoreProviderImpl implements ImageStoreProvider { return types; } + @Override + public boolean isScopeSupported(ScopeType scope) { + if ( scope == ScopeType.REGION ) + return true; + return false; + } + + } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index 073a157cb3d..eadb01df8f7 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -34,6 +34,7 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; +import com.cloud.storage.ScopeType; import com.cloud.utils.component.ComponentContext; public class SampleImageStoreProviderImpl implements ImageStoreProvider { @@ -79,4 +80,13 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { public HypervisorHostListener getHostListener() { return null; } + + @Override + public boolean isScopeSupported(ScopeType scope) { + if ( scope == ScopeType.ZONE) + return true; + return false; + } + + } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java index 625fcffb7ff..09f09c4ef98 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java @@ -44,7 +44,7 @@ import com.cloud.utils.component.ComponentContext; @Component public class SwiftImageStoreProviderImpl implements ImageStoreProvider { - private final String providerName = "Swift image store provider"; + private final String providerName = "Swift"; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject @@ -89,4 +89,12 @@ public class SwiftImageStoreProviderImpl implements ImageStoreProvider { return types; } + @Override + public boolean isScopeSupported(ScopeType scope) { + if ( scope == ScopeType.REGION ) + return true; + return false; + } + + } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index ca4c636ed74..77249680170 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -56,6 +56,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; @@ -1922,18 +1923,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C Long dcId = cmd.getZoneId(); String url = cmd.getUrl(); Map details = cmd.getDetails(); - - ScopeType scopeType = null; - String scope = cmd.getScope(); - if (scope != null) { - try { - scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); - } catch (Exception e) { - throw new InvalidParameterValueException("invalid scope" + scope); - } + ScopeType scopeType = ScopeType.ZONE; + if ( dcId == null ){ + scopeType = ScopeType.REGION; } - if (scopeType == ScopeType.ZONE && dcId == null) { - throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); + + // check if scope is supported by store provider + if ( !((ImageStoreProvider)storeProvider).isScopeSupported(scopeType)){ + throw new InvalidParameterValueException("Image store provider " + providerName + " does not support scope " + scopeType); + } + + // check if we have already image stores from other different providers, we currently are not supporting image stores from different + // providers co-existing + List imageStores = _imageStoreDao.listAll(); + for ( ImageStoreVO store : imageStores){ + if (!store.getProviderName().equalsIgnoreCase(providerName)){ + throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + " already added"); + } } if (dcId != null) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 2892e0081c2..f4ad36e64ed 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -325,7 +325,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (storeUuid != null) { imageStore = this.dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image); } else { - List stores = this.dataStoreMgr.getImageStores(new ZoneScope(zoneId)); + List stores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); if (stores.size() > 1) { throw new CloudRuntimeException("multiple image stores, don't know which one to use"); } @@ -1718,7 +1718,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId); snapshot = _snapshotDao.findById(snapshotId); ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); - List store = this.dataStoreMgr.getImageStores(scope); + List store = this.dataStoreMgr.getImageStoresByScope(scope); if (store.size() > 1) { throw new CloudRuntimeException("muliple image data store, don't know which one to use"); } From 02686583cfada2c5705ac6f37c2ddf4c474df7e5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 10 Apr 2013 18:02:53 -0700 Subject: [PATCH 015/303] First draft of register template using image store. --- .../user/template/RegisterTemplateCmd.java | 11 +- .../subsystem/api/storage/DataStore.java | 1 + .../api/storage/DataStoreManager.java | 2 +- .../storage/datastore/db/ImageStoreDao.java | 6 +- .../datastore/db/SnapshotDataStoreDao.java | 3 +- .../datastore/db/SnapshotDataStoreVO.java | 6 +- .../datastore/db/TemplateDataStoreDao.java | 9 +- .../datastore/db/TemplateDataStoreVO.java | 8 +- .../datastore/db/VolumeDataStoreDao.java | 3 +- .../datastore/db/VolumeDataStoreVO.java | 6 +- .../storage/image/ImageDataFactoryImpl.java | 8 +- .../storage/image/ImageServiceImpl.java | 33 +- .../ImageStoreProviderManagerImpl.java | 5 +- .../storage/image/store/ImageStoreImpl.java | 2 +- .../snapshot/SnapshotDataFactoryImpl.java | 4 +- .../datastore/DataStoreManagerImpl.java | 5 +- .../datastore/ObjectInDataStoreManager.java | 4 +- .../ObjectInDataStoreManagerImpl.java | 137 +++--- .../datastore/ImageStoreProviderManager.java | 3 +- .../storage/image/db/ImageStoreDaoImpl.java | 14 +- .../image/db/SnapshotDataStoreDaoImpl.java | 4 +- .../image/db/TemplateDataStoreDaoImpl.java | 43 +- .../image/db/VolumeDataStoreDaoImpl.java | 3 +- .../storage/volume/VolumeObject.java | 16 +- .../CloudStackImageStoreDriverImpl.java | 28 +- .../driver/S3ImageStoreDriverImpl.java | 28 +- .../driver/SwiftImageStoreDriverImpl.java | 28 +- .../com/cloud/storage/TemplateProfile.java | 75 ++-- .../storage/download/DownloadListener.java | 117 +++-- .../storage/download/DownloadMonitor.java | 14 +- .../storage/download/DownloadMonitorImpl.java | 415 ++++++++++-------- .../SecondaryStorageManagerImpl.java | 109 +++-- .../secondary/SecondaryStorageVmManager.java | 11 +- .../template/HypervisorTemplateAdapter.java | 33 +- .../com/cloud/template/TemplateAdapter.java | 14 +- .../cloud/template/TemplateAdapterBase.java | 91 ++-- 36 files changed, 738 insertions(+), 561 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java index c9da0c28cd6..f93c9f4254c 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java @@ -110,11 +110,7 @@ public class RegisterTemplateCmd extends BaseCmd { @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class, description="Register template for the project") private Long projectId; - - @Parameter(name=ApiConstants.IMAGE_STORE_UUID, type=CommandType.STRING, - description="Image store uuid") - private String imageStoreUuid; - + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="Template details in key/value pairs.") protected Map details; @@ -193,10 +189,7 @@ public class RegisterTemplateCmd extends BaseCmd { public String getTemplateTag() { return templateTag; } - - public String getImageStoreUuid() { - return this.imageStoreUuid; - } + public Map getDetails() { if (details == null || details.isEmpty()) { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java index f101f243047..10f869c39fe 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java @@ -23,6 +23,7 @@ public interface DataStore { String getUuid(); String getUri(); Scope getScope(); + String getName(); DataObject create(DataObject obj); boolean delete(DataObject obj); } 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 f940e8e9803..def3b96d331 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 @@ -26,7 +26,7 @@ public interface DataStoreManager { public DataStore getDataStore(long storeId, DataStoreRole role); public DataStore getPrimaryDataStore(long storeId); public DataStore getDataStore(String uuid, DataStoreRole role); - public List getImageStoresByScope(Scope scope); + public List getImageStoresByScope(ZoneScope scope); public List getImageStoresByProvider(String provider); public DataStore registerDataStore(Map params, String providerUuid); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index fbd09884d1f..8d6acbdf011 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -21,12 +21,14 @@ package org.apache.cloudstack.storage.datastore.db; import java.util.List; -import com.cloud.storage.ScopeType; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; + + import com.cloud.utils.db.GenericDao; public interface ImageStoreDao extends GenericDao { public ImageStoreVO findByName(String name); public List findByProvider(String provider); - public List findByScope(ScopeType scope); + public List findByScope(ZoneScope scope); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index 4d92fd3311d..91ffdaa01c2 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -19,13 +19,14 @@ package org.apache.cloudstack.storage.datastore.db; import java.util.List; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface SnapshotDataStoreDao extends GenericDao, StateDao { +public interface SnapshotDataStoreDao extends GenericDao, StateDao { public List listByStoreId(long id); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index 0f9c95ad8cf..c257fb5c39c 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -99,8 +99,8 @@ public class SnapshotDataStoreVO implements StateObject, StateDao { +public interface TemplateDataStoreDao extends GenericDao, StateDao { public List listByStoreId(long id); public List listLiveByStoreId(long id); public void deletePrimaryRecordsForStore(long id); + + List listByTemplateStoreStatus(long templateId, long storeId, State... states); + + TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index 4e48437ec2a..312fd119adc 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -32,7 +32,6 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; -import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; @@ -118,8 +117,8 @@ public class TemplateDataStoreVO implements StateObject, StateDao { +public interface VolumeDataStoreDao extends GenericDao, StateDao { public List listByStoreId(long id); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index 1fb61845fcc..185b12b52f1 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -121,8 +121,8 @@ public class VolumeDataStoreVO implements StateObject extends AsyncRpcConext { final TemplateInfo srcTemplate; final DataStore store; @@ -68,39 +68,30 @@ public class ImageServiceImpl implements ImageService { this.templateOnStore = templateOnStore; } } - + @Override public AsyncCallFuture createTemplateAsync( TemplateInfo template, DataStore store) { TemplateObject to = (TemplateObject) template; AsyncCallFuture future = new AsyncCallFuture(); - try { - to.stateTransit(TemplateEvent.CreateRequested); - } catch (NoTransitionException e) { - s_logger.debug("Failed to transit state:", e); - CommandResult result = new CommandResult(); - result.setResult(e.toString()); - future.complete(result); - return future; - } - + // persist template_store_ref entry DataObject templateOnStore = store.create(template); + // update template_store_ref state templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); - - CreateTemplateContext context = new CreateTemplateContext(null, + + CreateTemplateContext context = new CreateTemplateContext(null, template, future, store, templateOnStore ); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().createTemplateCallback(null, null)) - .setContext(context); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); store.getDriver().createAsync(templateOnStore, caller); return future; } - - protected Void createTemplateCallback(AsyncCallbackDispatcher callback, + + protected Void createTemplateCallback(AsyncCallbackDispatcher callback, CreateTemplateContext context) { TemplateObject template = (TemplateObject)context.srcTemplate; AsyncCallFuture future = context.future; @@ -118,7 +109,7 @@ public class ImageServiceImpl implements ImageService { future.complete(result); return null; } - + try { templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); template.stateTransit(TemplateEvent.OperationSucceeded); @@ -128,7 +119,7 @@ public class ImageServiceImpl implements ImageService { future.complete(result); return null; } - + future.complete(result); return null; } 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 642821f77b5..dbcfb765e1d 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 @@ -30,6 +30,7 @@ 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.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; @@ -93,8 +94,8 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager } @Override - public List listImageStoresByScope(Scope scope) { - List stores = dataStoreDao.findByScope(scope.getScopeType()); + public List listImageStoresByScope(ZoneScope scope) { + List stores = dataStoreDao.findByScope(scope); List imageStores = new ArrayList(); for (ImageStoreVO store : stores) { imageStores.add(getImageStore(store.getId())); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 90290d865f7..7e143cb6f06 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -94,7 +94,7 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public String getUri() { - return this.imageDataStoreVO.getProtocol() + "://" + "?" + EncodingType.ROLE + "=" + this.getRole(); + return this.imageDataStoreVO.getUrl(); } @Override diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java index fa7772a979d..0bd40d35122 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java @@ -51,7 +51,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { @Override public SnapshotInfo getSnapshot(long snapshotId, DataStore store) { SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId); - DataObjectInStore obj = objMap.findObject(snapshot.getUuid(), DataObjectType.SNAPSHOT, store.getUuid(), store.getRole()); + DataObjectInStore obj = objMap.findObject(snapshot.getId(), DataObjectType.SNAPSHOT, store.getId(), store.getRole()); if (obj == null) { return null; } @@ -71,7 +71,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { } return so; } - + @Override public SnapshotInfo getSnapshot(DataObject obj, DataStore store) { SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(obj.getId()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 8f8d3c92c52..eb233aa3f8b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -27,6 +27,7 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.springframework.stereotype.Component; @@ -63,8 +64,10 @@ public class DataStoreManagerImpl implements DataStoreManager { throw new CloudRuntimeException("un recognized type" + role); } + + @Override - public List getImageStoresByScope(Scope scope) { + public List getImageStoresByScope(ZoneScope scope) { return imageDataStoreMgr.listImageStoresByScope(scope); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index d170f5c707a..17b782ab6a0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -29,8 +29,8 @@ public interface ObjectInDataStoreManager { public DataObject create(DataObject template, DataStore dataStore); public DataObject get(DataObject dataObj, DataStore store); public boolean update(DataObject vo, Event event) throws NoTransitionException; - DataObjectInStore findObject(String uuid, DataObjectType type, - String dataStoreUuid, DataStoreRole role); + DataObjectInStore findObject(long objId, DataObjectType type, + long dataStoreId, DataStoreRole role); DataObjectInStore findObject(DataObject obj, DataStore store); DataStore findStore(String objUuid, DataObjectType type, DataStoreRole role); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 87ba1d216c5..80badc54d30 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -29,15 +29,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.storage.db.ObjectInDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; @@ -56,11 +60,11 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { @Inject VolumeDataFactory volumeFactory; @Inject - ObjectInDataStoreDao objectDataStoreDao; + TemplateDataStoreDao templateDataStoreDao; @Inject - VolumeHostDao volumeHostDao; + SnapshotDataStoreDao snapshotDataStoreDao; @Inject - VMTemplateHostDao templateHostDao; + VolumeDataStoreDao volumeDataStoreDao; @Inject VMTemplatePoolDao templatePoolDao; @Inject @@ -101,28 +105,38 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { @Override public DataObject create(DataObject obj, DataStore dataStore) { - if (obj.getType() == DataObjectType.TEMPLATE && dataStore.getRole() == DataStoreRole.Primary) { - VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); - vo = templatePoolDao.persist(vo); + if (dataStore.getRole() == DataStoreRole.Primary) { + if ( obj.getType() == DataObjectType.TEMPLATE){ + VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); + vo = templatePoolDao.persist(vo); + } } else { - ObjectInDataStoreVO vo = new ObjectInDataStoreVO(); - vo.setDataStoreRole(dataStore.getRole()); - vo.setDataStoreUuid(dataStore.getUuid()); - vo.setObjectType(obj.getType()); - vo.setObjectUuid(obj.getUuid()); - vo = objectDataStoreDao.persist(vo); + // Image store + switch ( obj.getType()){ + case TEMPLATE: + TemplateDataStoreVO ts = new TemplateDataStoreVO(); + ts.setTemplateId(obj.getId()); + ts.setDataStoreId(dataStore.getId()); + ts = templateDataStoreDao.persist(ts); + break; + case SNAPSHOT: + SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); + ss.setSnapshotId(obj.getId()); + ss.setDataStoreId(dataStore.getId()); + ss = snapshotDataStoreDao.persist(ss); + break; + case VOLUME: + VolumeDataStoreVO vs = new VolumeDataStoreVO(); + vs.setVolumeId(obj.getId()); + vs.setDataStoreId(dataStore.getId()); + vs = volumeDataStoreDao.persist(vs); + break; + } } - if (obj.getType() == DataObjectType.TEMPLATE) { - return imageFactory.getTemplate(obj, dataStore); - } else if (obj.getType() == DataObjectType.VOLUME) { - return volumeFactory.getVolume(obj, dataStore); - } else if (obj.getType() == DataObjectType.SNAPSHOT) { - return snapshotFactory.getSnapshot(obj, dataStore); - } - throw new CloudRuntimeException("unknown type"); + return this.get(obj, dataStore); } - + @Override public boolean update(DataObject data, Event event) throws NoTransitionException { @@ -132,8 +146,17 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { "can't find mapping in ObjectInDataStore table for: " + data); } - - if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { + + if ( data.getDataStore().getRole() == DataStoreRole.Image){ + switch (data.getType()){ + case TEMPLATE: + this.stateMachines.transitTo(obj, event, null, templateDataStoreDao); + case SNAPSHOT: + this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao); + case VOLUME: + this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao); + } + } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { try { this.stateMachines.transitTo(obj, event, null, templatePoolDao); @@ -145,7 +168,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } } } else { - this.stateMachines.transitTo(obj, event, null, objectDataStoreDao); + throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); } return true; } @@ -155,47 +178,53 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { if (dataObj.getType() == DataObjectType.TEMPLATE) { return imageFactory.getTemplate(dataObj, store); } else if (dataObj.getType() == DataObjectType.VOLUME) { - return volumeFactory.getVolume(dataObj, store); + return volumeFactory.getVolume(dataObj, store); + } else if (dataObj.getType() == DataObjectType.SNAPSHOT) { + return snapshotFactory.getSnapshot(dataObj, store); } + throw new CloudRuntimeException("unknown type"); } @Override public DataObjectInStore findObject(DataObject obj, DataStore store) { - DataObjectInStore vo = null; - SearchCriteriaService sc = SearchCriteria2.create(ObjectInDataStoreVO.class); - - if (store.getRole() == DataStoreRole.Image) { - sc.addAnd(sc.getEntity().getDataStoreUuid(), Op.EQ, store.getUuid()); - sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, store.getRole()); - sc.addAnd(sc.getEntity().getObjectUuid(), Op.EQ, obj.getUuid()); - sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, obj.getType()); - vo = sc.find(); - } else if (obj.getType() == DataObjectType.TEMPLATE && store.getRole() == DataStoreRole.Primary) { - vo = templatePoolDao.findByPoolTemplate(store.getId(), obj.getId()); - } else { - s_logger.debug("unknown type: " + obj.getType() + " " + store.getRole()); - throw new CloudRuntimeException("unknown type"); - } - return vo; + return findObject(obj.getId(), obj.getType(), store.getId(), store.getRole()); } + @Override - public DataObjectInStore findObject(String uuid, DataObjectType type, - String dataStoreUuid, DataStoreRole role) { + public DataObjectInStore findObject(long objId, DataObjectType type, + long dataStoreId, DataStoreRole role) { DataObjectInStore vo = null; - SearchCriteriaService sc = SearchCriteria2.create(ObjectInDataStoreVO.class); - if (role == DataStoreRole.Image) { - sc.addAnd(sc.getEntity().getDataStoreUuid(), Op.EQ, dataStoreUuid); - sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role); - sc.addAnd(sc.getEntity().getObjectUuid(), Op.EQ, uuid); - sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type); - vo = sc.find(); + switch (type){ + case TEMPLATE: + SearchCriteria ts = templateDataStoreDao.createSearchCriteria(); + ts.addAnd("templateId", SearchCriteria.Op.EQ, objId); + ts.addAnd("dataStoreId", SearchCriteria.Op.EQ, dataStoreId); + vo = templateDataStoreDao.findOneBy(ts); + case SNAPSHOT: + SearchCriteria ss = snapshotDataStoreDao.createSearchCriteria(); + ss.addAnd("snapshotId", SearchCriteria.Op.EQ, objId); + ss.addAnd("dataStoreId", SearchCriteria.Op.EQ, objId); + vo = snapshotDataStoreDao.findOneBy(ss); + case VOLUME: + SearchCriteria vs = volumeDataStoreDao.createSearchCriteria(); + vs.addAnd("volumeId", SearchCriteria.Op.EQ, objId); + vs.addAnd("dataStoreId", SearchCriteria.Op.EQ, objId); + vo = volumeDataStoreDao.findOneBy(vs); + } + } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { + vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); + } else { + s_logger.debug("Invalid data or store type: " + type + " " + role); + throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role); } + return vo; + } - + @Override public DataStore findStore(String objUuid, DataObjectType type, DataStoreRole role) { DataStore store = null; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index bb5e20fdea0..2026346ccdc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -22,13 +22,14 @@ import java.util.List; 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.ZoneScope; import org.apache.cloudstack.storage.image.ImageStoreDriver; public interface ImageStoreProviderManager { ImageStoreEntity getImageStore(long dataStoreId); ImageStoreEntity getImageStore(String uuid); List listImageStores(); - List listImageStoresByScope(Scope scope); + List listImageStoresByScope(ZoneScope scope); List listImageStoreByProvider(String provider); boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index ab41a4b0deb..5bcf2f32691 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -24,6 +24,8 @@ import java.util.Map; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.log4j.Logger; @@ -40,7 +42,6 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class); private SearchBuilder nameSearch; private SearchBuilder providerSearch; - private SearchBuilder scopeSearch; @Override @@ -55,10 +56,6 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ); providerSearch.done(); - scopeSearch = createSearchBuilder(); - scopeSearch.and("scope", scopeSearch.entity().getScope(), SearchCriteria.Op.EQ); - scopeSearch.done(); - return true; } @@ -77,9 +74,10 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem } @Override - public List findByScope(ScopeType scope) { - SearchCriteria sc = scopeSearch.create(); - sc.setParameters("scope", scope); + public List findByScope(ZoneScope scope) { + SearchCriteria sc = createSearchCriteria(); + sc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION); + sc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); return listBy(sc); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index a1c4871caa3..6a6e04a52b3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -21,6 +21,7 @@ import java.util.Map; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; @@ -66,7 +67,8 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; private SearchBuilder liveStoreSearch; + private SearchBuilder storeTemplateStateSearch; + private SearchBuilder storeTemplateSearch; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -62,12 +64,27 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listByTemplateStoreStatus(long templateId, long storeId, State... states) { + SearchCriteria sc = storeTemplateStateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("store_id", storeId); + sc.setParameters("states", (Object[])states); + return search(sc, null); + } + + @Override + public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) { + SearchCriteria sc = storeTemplateSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index b8127ee3361..9a93f980b27 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -67,7 +67,8 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase callback) { + this.ssAgent = ssAgent; + this.sstore = store; + this.template = template; + this._vmTemplateStoreDao = dao; + this.downloadMonitor = downloadMonitor; + this.cmd = cmd; + this.templateStoreId = templStoreId; + initStateMachine(); + this.currState=getState(Status.NOT_DOWNLOADED.toString()); + this.timer = _timer; + this.timeoutTask = new TimeoutTask(this); + this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); + this._vmTemplateDao = templateDao; + this._resourceLimitMgr = _resourceLimitMgr; + this._accountMgr = _accountMgr; + this._alertMgr = _alertMgr; + this.callback = callback; + updateDatabase(Status.NOT_DOWNLOADED, ""); + } + + public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) { this.ssAgent = ssAgent; this.sserver = host; @@ -185,8 +218,8 @@ public class DownloadListener implements Listener { this._alertMgr = _alertMgr; updateDatabase(Status.NOT_DOWNLOADED, ""); } - - + + public void setCurrState(VMTemplateHostVO.Status currState) { this.currState = getState(currState.toString()); } @@ -198,7 +231,7 @@ public class DownloadListener implements Listener { stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this)); stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this)); } - + private DownloadState getState(String stateName) { return stateMap.get(stateName); } @@ -217,7 +250,7 @@ public class DownloadListener implements Listener { } catch (AgentUnavailableException e) { s_logger.debug("Send command failed", e); setDisconnected(); - } + } } } @@ -253,7 +286,7 @@ public class DownloadListener implements Listener { volumeHostDao.update(getVolumeHostId(), vo); } } - + public void log(String message, Level level) { if (template != null){ s_logger.log(level, message + ", template=" + template.getName() + " at host " + sserver.getName()); @@ -269,7 +302,15 @@ public class DownloadListener implements Listener { } return templateHostId; } - + + private Long getTemplateStoreId() { + if (templateStoreId == null){ + TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(sstore.getId(), template.getId()); + templateStoreId = templStore.getId(); + } + return templateStoreId; + } + private Long getVolumeHostId() { if (volumeHostId == null){ VolumeHostVO volHost = volumeHostDao.findByHostVolume(sserver.getId(), volume.getId()); @@ -282,14 +323,14 @@ public class DownloadListener implements Listener { downloadMonitor = monitor; } - + @Override public boolean isRecurring() { return false; } - + @Override public boolean processAnswers(long agentId, long seq, Answer[] answers) { boolean processed = false; @@ -307,7 +348,7 @@ public class DownloadListener implements Listener { } return processed; } - + private synchronized void transition(DownloadEvent event, Object evtObj) { if (currState == null) { return; @@ -328,7 +369,7 @@ public class DownloadListener implements Listener { public synchronized void updateDatabase(DownloadAnswer answer) { if (template != null){ - VMTemplateHostVO updateBuilder = vmTemplateHostDao.createForUpdate(); + TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); updateBuilder.setDownloadState(answer.getDownloadStatus()); updateBuilder.setLastUpdated(new Date()); @@ -338,9 +379,9 @@ public class DownloadListener implements Listener { updateBuilder.setInstallPath(answer.getInstallPath()); updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - - vmTemplateHostDao.update(getTemplateHostId(), updateBuilder); - + + _vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder); + if (answer.getCheckSum() != null) { VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); templateDaoBuilder.setChecksum(answer.getCheckSum()); @@ -363,7 +404,14 @@ public class DownloadListener implements Listener { com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } } - + // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column + Status dndStatus = answer.getDownloadStatus(); + if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){ + if ( callback != null ){ + CreateCmdResult result = new CreateCmdResult(null, null); + callback.complete(result); + } + } } else { VolumeHostVO updateBuilder = volumeHostDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); @@ -422,20 +470,21 @@ public class DownloadListener implements Listener { setDisconnected(); return true; } - + @Override public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { downloadMonitor.handleSysTemplateDownload(agent); } else if ( cmd instanceof StartupStorageCommand) { StartupStorageCommand storage = (StartupStorageCommand)cmd; - if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE || + if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE || storage.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE ) { downloadMonitor.addSystemVMTemplatesToHost(agent, storage.getTemplateInfo()); - downloadMonitor.handleTemplateSync(agent); + // DO we need to do sync here since we have been doing sync in StartupSecondaryStorageCommand? + // downloadMonitor.handleTemplateSync(agent); downloadMonitor.handleVolumeSync(agent); } - } else if ( cmd instanceof StartupSecondaryStorageCommand ) { + } else if ( cmd instanceof StartupSecondaryStorageCommand ) { downloadMonitor.handleSync(agent.getDataCenterId()); } } @@ -448,7 +497,7 @@ public class DownloadListener implements Listener { return cmd; } - + public void abandon() { transition(DownloadEvent.ABANDON_DOWNLOAD, null); } @@ -467,7 +516,7 @@ public class DownloadListener implements Listener { statusTask = new StatusTask(this, request); timer.schedule(statusTask, STATUS_POLL_INTERVAL); } - + public void scheduleTimeoutTask(long delay) { if (timeoutTask != null) timeoutTask.cancel(); @@ -477,7 +526,7 @@ public class DownloadListener implements Listener { log("Scheduling timeout at " + delay + " ms", Level.DEBUG); } } - + public void scheduleImmediateStatusCheck(RequestType request) { if (statusTask != null) statusTask.cancel(); statusTask = new StatusTask(this, request); @@ -495,7 +544,7 @@ public class DownloadListener implements Listener { public Date getLastUpdated() { return lastUpdated; } - + public void setLastUpdated() { lastUpdated = new Date(); } @@ -515,12 +564,12 @@ public class DownloadListener implements Listener { public void logDownloadStart() { } - + @Override public boolean processTimeout(long agentId, long seq) { return true; } - + @Override public int getTimeout() { return -1; diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index 897befa250b..b20973352d5 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -18,6 +18,10 @@ package com.cloud.storage.download; import java.util.Map; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; + import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; @@ -32,12 +36,12 @@ import com.cloud.utils.component.Manager; * */ public interface DownloadMonitor extends Manager{ - - public boolean downloadTemplateToStorage(VMTemplateVO template, Long zoneId); - + + public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + public void cancelAllDownloads(Long templateId); - public void handleTemplateSync(HostVO host); + public void handleTemplateSync(DataStore store); public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer) throws StorageUnavailableException; @@ -50,6 +54,6 @@ public interface DownloadMonitor extends Manager{ boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format); - void handleVolumeSync(HostVO ssHost); + void handleVolumeSync(HostVO ssHost); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 7ed6f3f27d6..70254def3f9 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -30,6 +30,12 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +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.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -118,15 +124,20 @@ import com.cloud.vm.dao.UserVmDao; import edu.emory.mathcs.backport.java.util.Collections; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; + @Component @Local(value={DownloadMonitor.class}) public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor { static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class); - - @Inject + + @Inject VMTemplateHostDao _vmTemplateHostDao; - @Inject + @Inject + TemplateDataStoreDao _vmTemplateStoreDao; + @Inject VMTemplateZoneDao _vmTemplateZoneDao; @Inject VMTemplatePoolDao _vmTemplatePoolDao; @@ -148,7 +159,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor SecondaryStorageVmManager _ssvmMgr; @Inject StorageManager _storageMgr ; - + @Inject private final DataCenterDao _dcDao = null; @Inject @@ -163,10 +174,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject TemplateManager templateMgr; - - @Inject + + @Inject private UsageEventDao _usageEventDao; - + @Inject private ClusterDao _clusterDao; @@ -186,10 +197,13 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor private Boolean _sslCopy = new Boolean(false); private String _copyAuthPasswd; private String _proxy = null; - protected SearchBuilder ReadyTemplateStatesSearch; + protected SearchBuilder ReadyTemplateStatesSearch; Timer _timer; + @Inject DataStoreManager storeMgr; + + final Map _listenerTemplateMap = new ConcurrentHashMap(); final Map _listenerMap = new ConcurrentHashMap(); final Map _listenerVolumeMap = new ConcurrentHashMap(); @@ -203,20 +217,20 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor final Map configs = _configDao.getConfiguration("ManagementServer", params); _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy")); _proxy = configs.get(Config.SecStorageProxy.key()); - + String cert = configs.get("secstorage.ssl.cert.domain"); if (!"realhostip.com".equalsIgnoreCase(cert)) { s_logger.warn("Only realhostip.com ssl cert is supported, ignoring self-signed and other certs"); } - + _copyAuthPasswd = configs.get("secstorage.copy.password"); - + _agentMgr.registerForHostEvents(new DownloadListener(this), true, false, false); - - ReadyTemplateStatesSearch = _vmTemplateHostDao.createSearchBuilder(); - ReadyTemplateStatesSearch.and("download_state", ReadyTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); + + ReadyTemplateStatesSearch = _vmTemplateStoreDao.createSearchBuilder(); + ReadyTemplateStatesSearch.and("state", ReadyTemplateStatesSearch.entity().getState(), SearchCriteria.Op.EQ); ReadyTemplateStatesSearch.and("destroyed", ReadyTemplateStatesSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - ReadyTemplateStatesSearch.and("host_id", ReadyTemplateStatesSearch.entity().getHostId(), SearchCriteria.Op.EQ); + ReadyTemplateStatesSearch.and("store_id", ReadyTemplateStatesSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); SearchBuilder TemplatesWithNoChecksumSearch = _templateDao.createSearchBuilder(); TemplatesWithNoChecksumSearch.and("checksum", TemplatesWithNoChecksumSearch.entity().getChecksum(), SearchCriteria.Op.NULL); @@ -225,7 +239,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor ReadyTemplateStatesSearch.entity().getTemplateId(), JoinBuilder.JoinType.INNER); TemplatesWithNoChecksumSearch.done(); ReadyTemplateStatesSearch.done(); - + return true; } @@ -239,13 +253,13 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor public boolean stop() { return true; } - - public boolean isTemplateUpdateable(Long templateId, Long hostId) { - List downloadsInProgress = - _vmTemplateHostDao.listByTemplateHostStatus(templateId.longValue(), hostId.longValue(), VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.DOWNLOADED); + + public boolean isTemplateUpdateable(Long templateId, Long storeId) { + List downloadsInProgress = + _vmTemplateStoreDao.listByTemplateStoreStatus(templateId, storeId, ObjectInDataStoreStateMachine.State.Creating, ObjectInDataStoreStateMachine.State.Creating2, ObjectInDataStoreStateMachine.State.Ready); return (downloadsInProgress.size() == 0); } - + @Override public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer) throws StorageUnavailableException{ @@ -278,12 +292,12 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor throw new CloudRuntimeException("Cant copy the template as the template's size " +srcTmpltHost.getSize()+ " is greater than max.template.iso.size " + maxTemplateSizeInBytes); } - + if(destTmpltHost != null) { start(); String sourceChecksum = this.templateMgr.getChecksum(srcTmpltHost.getHostId(), srcTmpltHost.getInstallPath()); - DownloadCommand dcmd = - new DownloadCommand(destServer.getStorageUrl(), url, template, TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes); + DownloadCommand dcmd = + new DownloadCommand(destServer.getStorageUrl(), url, template, TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, destTmpltHost.getJobId(), RequestType.GET_OR_RESTART); @@ -305,7 +319,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if( old != null ) { old.abandon(); } - + try { send(ssAhost.getId(), dcmd, dl); return true; @@ -316,10 +330,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor e.printStackTrace(); } } - + return false; } - + private String generateCopyUrl(String ipAddress, String dir, String path){ String hostname = ipAddress; String scheme = "http"; @@ -328,9 +342,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor hostname = hostname + ".realhostip.com"; scheme = "https"; } - return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path; + return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path; } - + private String generateCopyUrl(HostVO sourceServer, VMTemplateHostVO srcTmpltHost) { List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, sourceServer.getDataCenterId(), State.Running); if (ssVms.size() > 0) { @@ -341,7 +355,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } return generateCopyUrl(ssVm.getPublicIpAddress(), sourceServer.getParent(), srcTmpltHost.getInstallPath()); } - + VMTemplateVO tmplt = _templateDao.findById(srcTmpltHost.getTemplateId()); HypervisorType hyperType = tmplt.getHypervisorType(); /*No secondary storage vm yet*/ @@ -351,43 +365,43 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor return null; } - private void downloadTemplateToStorage(VMTemplateVO template, HostVO sserver) { + private void initiateTemplateDownload(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { boolean downloadJobExists = false; - VMTemplateHostVO vmTemplateHost = null; + TemplateDataStoreVO vmTemplateStore = null; - vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId()); - if (vmTemplateHost == null) { - vmTemplateHost = new VMTemplateHostVO(sserver.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); - _vmTemplateHostDao.persist(vmTemplateHost); - } else if ((vmTemplateHost.getJobId() != null) && (vmTemplateHost.getJobId().length() > 2)) { + vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); + // we should already persist one entry in template_store_ref table, so vmTemplateStore should not be null + if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { downloadJobExists = true; } - + Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); - String secUrl = sserver.getStorageUrl(); - if(vmTemplateHost != null) { + String secUrl = store.getUri(); + if(vmTemplateStore != null) { start(); DownloadCommand dcmd = new DownloadCommand(secUrl, template, maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { - dcmd = new DownloadProgressCommand(dcmd, vmTemplateHost.getJobId(), RequestType.GET_OR_RESTART); + dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); } - if (vmTemplateHost.isCopy()) { + if (vmTemplateStore.isCopy()) { dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(sserver); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); if( ssAhost == null ) { - s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName()); + s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName()); return; } - DownloadListener dl = new DownloadListener(ssAhost, sserver, template, _timer, _vmTemplateHostDao, vmTemplateHost.getId(), this, dcmd, _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr); + DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); if (downloadJobExists) { - dl.setCurrState(vmTemplateHost.getDownloadState()); + // due to handling existing download job issues, we still keep downloadState in template_store_ref to avoid big change in DownloadListener to use + // new ObjectInDataStore.State transition. TODO: fix this later to be able to remove downloadState from template_store_ref. + dl.setCurrState(vmTemplateStore.getDownloadState()); } DownloadListener old = null; - synchronized (_listenerMap) { - old = _listenerMap.put(vmTemplateHost, dl); + synchronized (_listenerTemplateMap) { + old = _listenerTemplateMap.put(vmTemplateStore, dl); } if( old != null ) { old.abandon(); @@ -396,7 +410,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor try { send(ssAhost.getId(), dcmd, dl); } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + sserver.getName(), e); + s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + store.getName(), e); dl.setDisconnected(); dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } @@ -406,39 +420,26 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Override - public boolean downloadTemplateToStorage(VMTemplateVO template, Long zoneId) { - List dcs = new ArrayList(); - if (zoneId == null) { - dcs.addAll(_dcDao.listAll()); - } else { - dcs.add(_dcDao.findById(zoneId)); - } + public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); - boolean isPublic = template.isFeatured() || template.isPublicTemplate(); - for ( DataCenterVO dc : dcs ) { - List ssHosts = _ssvmMgr.listAllTypesSecondaryStorageHostsInOneZone(dc.getId()); - for ( HostVO ssHost : ssHosts ) { - if (isTemplateUpdateable(templateId, ssHost.getId())) { - initiateTemplateDownload(templateId, ssHost); - if (! isPublic ) { - break; - } - } - } - } + if (isTemplateUpdateable(templateId, store.getId())) { + if ( template != null && template.getUrl() != null ){ + initiateTemplateDownload(template, store, callback); + } + } return true; } - + @Override public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format) { - + List ssHosts = _ssvmMgr.listAllTypesSecondaryStorageHostsInOneZone(zoneId); Collections.shuffle(ssHosts); HostVO ssHost = ssHosts.get(0); downloadVolumeToStorage(volume, ssHost, url, checkSum, format); return true; } - + private void downloadVolumeToStorage(VolumeVO volume, HostVO sserver, String url, String checkSum, ImageFormat format) { boolean downloadJobExists = false; VolumeHostVO volumeHost = null; @@ -451,7 +452,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) { downloadJobExists = true; } - + Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes(); String secUrl = sserver.getStorageUrl(); @@ -463,7 +464,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); dcmd.setResourceType(ResourceType.VOLUME); } - + HostVO ssvm = _ssvmMgr.pickSsvmHost(sserver); if( ssvm == null ) { s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName()); @@ -471,7 +472,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } DownloadListener dl = new DownloadListener(ssvm, sserver, volume, _timer, _volumeHostDao, volumeHost.getId(), this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr); - + if (downloadJobExists) { dl.setCurrState(volumeHost.getDownloadState()); } @@ -493,15 +494,16 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } - - private void initiateTemplateDownload(Long templateId, HostVO ssHost) { +/* + private void initiateTemplateDownload(Long templateId, DataStore store) { VMTemplateVO template = _templateDao.findById(templateId); if (template != null && (template.getUrl() != null)) { //find all storage hosts and tell them to initiate download - downloadTemplateToStorage(template, ssHost); + downloadTemplateToStorage(template, store); } - + } + */ @DB public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { @@ -511,11 +513,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor _listenerMap.remove(vmTemplateHost); } } - + VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId()); - + Transaction txn = Transaction.currentTxn(); - txn.start(); + txn.start(); if (dnldStatus == Status.DOWNLOADED) { long size = -1; @@ -548,14 +550,14 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor _listenerVolumeMap.remove(volumeHost); } } - + VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId()); - + Transaction txn = Transaction.currentTxn(); - txn.start(); + txn.start(); if (dnldStatus == Status.DOWNLOADED) { - + //Create usage event long size = -1; if(volumeHost!=null){ @@ -590,38 +592,45 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } Set toBeDownloaded = new HashSet(); + List ssHosts = this.storeMgr.getImageStoresByScope(new ZoneScope(host.getDataCenterId())); + if (ssHosts == null || ssHosts.isEmpty()){ + return; + } + /* List ssHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.SecondaryStorage, host.getDataCenterId()); if (ssHosts == null || ssHosts.isEmpty()) { return; } + */ /*Download all the templates in zone with the same hypervisortype*/ - for ( HostVO ssHost : ssHosts) { + for ( DataStore ssHost : ssHosts) { List rtngTmplts = _templateDao.listAllSystemVMTemplates(); List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); - - + + for (VMTemplateVO rtngTmplt : rtngTmplts) { if (rtngTmplt.getHypervisorType() == hostHyper) { toBeDownloaded.add(rtngTmplt); } } - + for (VMTemplateVO builtinTmplt : defaultBuiltin) { if (builtinTmplt.getHypervisorType() == hostHyper) { toBeDownloaded.add(builtinTmplt); } } - + for (VMTemplateVO template: toBeDownloaded) { VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) { - downloadTemplateToStorage(template, ssHost); + //TODO: pass callback here + initiateTemplateDownload(template, ssHost, null); } } } } - - @Override + + @Override public void addSystemVMTemplatesToHost(HostVO host, Map templateInfos){ if ( templateInfos == null ) { return; @@ -642,21 +651,26 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } } - + @Override public void handleSync(Long dcId) { if (dcId != null) { List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId); for (HostVO ssHost : ssHosts) { - handleTemplateSync(ssHost); + //handleTemplateSync(ssHost); handleVolumeSync(ssHost); } } + List imageStores = this.storeMgr.getImageStoresByScope(new ZoneScope(dcId)); + for (DataStore store : imageStores){ + handleTemplateSync(store); + } } - - private Map listTemplate(HostVO ssHost) { - ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getStorageUrl()); - Answer answer = _agentMgr.sendToSecStorage(ssHost, cmd); + + private Map listTemplate(DataStore ssHost) { + ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri()); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost); + Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd); if (answer != null && answer.getResult()) { ListTemplateAnswer tanswer = (ListTemplateAnswer)answer; return tanswer.getTemplateInfo(); @@ -664,11 +678,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (s_logger.isDebugEnabled()) { s_logger.debug("can not list template for secondary storage host " + ssHost.getId()); } - } - + } + return null; } - + private Map listVolume(HostVO ssHost) { ListVolumeCommand cmd = new ListVolumeCommand(ssHost.getStorageUrl()); Answer answer = _agentMgr.sendToSecStorage(ssHost, cmd); @@ -679,11 +693,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (s_logger.isDebugEnabled()) { s_logger.debug("Can not list volumes for secondary storage host " + ssHost.getId()); } - } - + } + return null; } - + private Map listTemplate(SwiftVO swift) { if (swift == null) { return null; @@ -700,14 +714,14 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } return null; } - + @Override public void handleVolumeSync(HostVO ssHost) { if (ssHost == null) { s_logger.warn("Huh? ssHost is null"); return; } - long sserverId = ssHost.getId(); + long sserverId = ssHost.getId(); if (!(ssHost.getType() == Host.Type.SecondaryStorage || ssHost.getType() == Host.Type.LocalSecondaryStorage)) { s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host"); return; @@ -717,7 +731,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (volumeInfos == null) { return; } - + List dbVolumes = _volumeHostDao.listBySecStorage(sserverId); List toBeDownloaded = new ArrayList(dbVolumes); for (VolumeHostVO volumeHost : dbVolumes){ @@ -779,17 +793,17 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (volumeHost.getDownloadState() != Status.DOWNLOADED) { s_logger.info("Volume Sync did not find " + volume.getName() + " ready on server " + sserverId + ", will request download to start/resume shortly"); toBeDownloaded.add(volumeHost); - } + } } - + //Download volumes which haven't been downloaded yet. if (toBeDownloaded.size() > 0) { for (VolumeHostVO volumeHost : toBeDownloaded) { if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download continue; - } + } s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + ssHost.getName()); - downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), ssHost, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat()); + downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), ssHost, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat()); } } @@ -804,32 +818,36 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor s_logger.error(err); return; } - + String description = "Deleted volume " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " since it isn't in the database"; s_logger.info(description); } } - - @Override - public void handleTemplateSync(HostVO ssHost) { - if (ssHost == null) { - s_logger.warn("Huh? ssHost is null"); - return; - } - long sserverId = ssHost.getId(); - long zoneId = ssHost.getDataCenterId(); - if (!(ssHost.getType() == Host.Type.SecondaryStorage || ssHost.getType() == Host.Type.LocalSecondaryStorage)) { - s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host"); - return; - } - Map templateInfos = listTemplate(ssHost); + @Override + public void handleTemplateSync(DataStore ssStore) { + if (ssStore == null) { + s_logger.warn("Huh? image store is null"); + return; + } + long storeId = ssStore.getId(); + Long zoneId = ssStore.getScope().getScopeId(); + + Map templateInfos = listTemplate(ssStore); if (templateInfos == null) { return; } Set toBeDownloaded = new HashSet(); - List allTemplates = _templateDao.listAllInZone(zoneId); + List allTemplates = null; + if (zoneId == null){ + // region wide store + allTemplates = _templateDao.listAll(); + } + else{ + // zone wide store + allTemplates = _templateDao.listAllInZone(zoneId); + } List rtngTmplts = _templateDao.listAllSystemVMTemplates(); List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); @@ -853,34 +871,34 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor for (VMTemplateVO tmplt : allTemplates) { String uniqueName = tmplt.getUniqueName(); - VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(sserverId, tmplt.getId()); + TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); if (templateInfos.containsKey(uniqueName)) { TemplateInfo tmpltInfo = templateInfos.remove(uniqueName); toBeDownloaded.remove(tmplt); - if (tmpltHost != null) { + if (tmpltStore != null) { s_logger.info("Template Sync found " + uniqueName + " already in the template host table"); - if (tmpltHost.getDownloadState() != Status.DOWNLOADED) { - tmpltHost.setErrorString(""); + if (tmpltStore.getDownloadState() != Status.DOWNLOADED) { + tmpltStore.setErrorString(""); } if (tmpltInfo.isCorrupted()) { - tmpltHost.setDownloadState(Status.DOWNLOAD_ERROR); - String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltHost.getId(); - tmpltHost.setErrorString(msg); + tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR); + String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId(); + tmpltStore.setErrorString(msg); s_logger.info("msg"); if (tmplt.getUrl() == null) { - msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in secondary storage: " + tmpltHost.getHostId(); + msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId(); s_logger.warn(msg); } else { toBeDownloaded.add(tmplt); } } else { - tmpltHost.setDownloadPercent(100); - tmpltHost.setDownloadState(Status.DOWNLOADED); - tmpltHost.setInstallPath(tmpltInfo.getInstallPath()); - tmpltHost.setSize(tmpltInfo.getSize()); - tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize()); - tmpltHost.setLastUpdated(new Date()); + tmpltStore.setDownloadPercent(100); + tmpltStore.setDownloadState(Status.DOWNLOADED); + tmpltStore.setInstallPath(tmpltInfo.getInstallPath()); + tmpltStore.setSize(tmpltInfo.getSize()); + tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); + tmpltStore.setLastUpdated(new Date()); if (tmpltInfo.getSize() > 0) { long accountId = tmplt.getAccountId(); @@ -890,7 +908,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl())); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, ssHost.getDataCenterId(), + _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, null, e.getMessage(), e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), @@ -898,39 +916,62 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } } - _vmTemplateHostDao.update(tmpltHost.getId(), tmpltHost); + _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore); } else { - tmpltHost = new VMTemplateHostVO(sserverId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); - tmpltHost.setSize(tmpltInfo.getSize()); - tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize()); - _vmTemplateHostDao.persist(tmpltHost); - VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId()); + tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); + tmpltStore.setSize(tmpltInfo.getSize()); + tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); + _vmTemplateStoreDao.persist(tmpltStore); + List dcs = new ArrayList(); + if (zoneId != null ){ + dcs.add(zoneId); + } + else{ + List zones = _dcDao.listAll(); + for (DataCenterVO zone : zones){ + dcs.add(zone.getId()); + } + } + for (Long id : dcs) { + VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, tmplt.getId()); + if (tmpltZoneVO == null) { + tmpltZoneVO = new VMTemplateZoneVO(id, tmplt.getId(), new Date()); + _vmTemplateZoneDao.persist(tmpltZoneVO); + } else { + tmpltZoneVO.setLastUpdated(new Date()); + _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); + } + } + } + + continue; + } + if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) { + s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly"); + + } else if (tmpltStore == null) { + s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly"); + TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); + _vmTemplateStoreDao.persist(templtStore); + List dcs = new ArrayList(); + if (zoneId != null ){ + dcs.add(zoneId); + } + else{ + List zones = _dcDao.listAll(); + for (DataCenterVO zone : zones){ + dcs.add(zone.getId()); + } + } + for (Long id : dcs) { + VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, tmplt.getId()); if (tmpltZoneVO == null) { - tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date()); + tmpltZoneVO = new VMTemplateZoneVO(id, tmplt.getId(), new Date()); _vmTemplateZoneDao.persist(tmpltZoneVO); } else { tmpltZoneVO.setLastUpdated(new Date()); _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); } - - } - - continue; - } - if (tmpltHost != null && tmpltHost.getDownloadState() != Status.DOWNLOADED) { - s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + sserverId + ", will request download to start/resume shortly"); - - } else if (tmpltHost == null) { - s_logger.info("Template Sync did not find " + uniqueName + " on the server " + sserverId + ", will request download shortly"); - VMTemplateHostVO templtHost = new VMTemplateHostVO(sserverId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); - _vmTemplateHostDao.persist(templtHost); - VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(zoneId, tmplt.getId()); - if (tmpltZoneVO == null) { - tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date()); - _vmTemplateZoneDao.persist(tmpltZoneVO); - } else { - tmpltZoneVO.setLastUpdated(new Date()); - _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); } } @@ -958,7 +999,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor // if this is private template, and there is no record for this // template in this sHost, skip if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) { - VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(sserverId, tmplt.getId()); + VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(storeId, tmplt.getId()); if (tmpltHost == null) { continue; } @@ -969,8 +1010,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor continue; } } - s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssHost.getName()); - downloadTemplateToStorage(tmplt, ssHost); + s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssStore.getName()); + //TODO: we should pass a callback here + initiateTemplateDownload(tmplt, ssStore, null); } } } @@ -980,16 +1022,17 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(ssHost.getStorageUrl(), tInfo.getInstallPath()); + DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(ssStore.getUri(), tInfo.getInstallPath()); try { - _agentMgr.sendToSecStorage(ssHost, dtCommand, null); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore); + _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); } catch (AgentUnavailableException e) { - String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + sserverId + " which isn't in the database"; + String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database"; s_logger.error(err); return; } - String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + sserverId + " since it isn't in the database"; + String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database"; s_logger.info(description); } } @@ -1012,10 +1055,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } } - + + /* private void checksumSync(long hostId){ - SearchCriteria sc = ReadyTemplateStatesSearch.create(); - sc.setParameters("download_state", com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + SearchCriteria sc = ReadyTemplateStatesSearch.create(); + sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready); sc.setParameters("host_id", hostId); List templateHostRefList = _vmTemplateHostDao.search(sc, null); @@ -1030,7 +1074,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } - + */ + private Long getMaxTemplateSizeInBytes() { try { return Long.parseLong(_configDao.getValue("max.template.iso.size")) * 1024L * 1024L * 1024L; @@ -1038,7 +1083,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor return null; } } - + private Long getMaxVolumeSizeInBytes() { try { return Long.parseLong(_configDao.getValue("storage.max.volume.upload.size")) * 1024L * 1024L * 1024L; @@ -1046,7 +1091,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor return null; } } - + private Proxy getHttpProxy() { if (_proxy == null) { return null; @@ -1058,7 +1103,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } catch (URISyntaxException e) { return null; } - } - + } + } - + diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index c94224b264c..bdac44d9a0d 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -5,7 +5,7 @@ // 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, @@ -29,6 +29,9 @@ import javax.ejb.Local; 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.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.log4j.Logger; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -95,6 +98,7 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.ScopeType; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateHostVO; @@ -199,7 +203,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar protected NetworkModel _networkModel; @Inject protected SnapshotDao _snapshotDao; - + @Inject private ClusterManager _clusterMgr; @@ -221,7 +225,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar protected CapacityDao _capacityDao; @Inject UserVmDetailsDao _vmDetailsDao; - @Inject + @Inject protected ResourceManager _resourceMgr; //@Inject // TODO this is a very strange usage, a singleton class need to inject itself? protected SecondaryStorageVmManager _ssvmMgr; @@ -233,7 +237,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar protected IPAddressDao _ipAddressDao = null; @Inject protected RulesManager _rulesMgr; - + @Inject KeystoreManager _keystoreMgr; private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL; @@ -254,7 +258,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar public SecondaryStorageManagerImpl() { _ssvmMgr = this; } - + @Override public SecondaryStorageVmVO startSecStorageVm(long secStorageVmId) { try { @@ -283,13 +287,13 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } return null; } - + @Override public boolean generateSetupCommand(Long ssHostId) { HostVO cssHost = _hostDao.findById(ssHostId); Long zoneId = cssHost.getDataCenterId(); if( cssHost.getType() == Host.Type.SecondaryStorageVM ) { - + SecondaryStorageVmVO secStorageVm = _secStorageVmDao.findByInstanceName(cssHost.getName()); if (secStorageVm == null) { s_logger.warn("secondary storage VM " + cssHost.getName() + " doesn't exist"); @@ -306,7 +310,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME); setupCmd = new SecStorageSetupCommand(secUrl, certs); } - + Answer answer = _agentMgr.easySend(ssHostId, setupCmd); if (answer != null && answer.getResult()) { SecStorageSetupAnswer an = (SecStorageSetupAnswer) answer; @@ -338,14 +342,14 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar s_logger.debug("Successfully programmed secondary storage " + host.getName() + " in secondary storage VM " + ssVm.getInstanceName()); } return false; - } + } } } return true; } - - - @Override + + + @Override public boolean deleteHost(Long hostId) { List snapshots = _snapshotDao.listByHostId(hostId); if( snapshots != null && !snapshots.isEmpty()) { @@ -362,10 +366,10 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar host.setGuid(null); _hostDao.update(hostId, host); _hostDao.remove(hostId); - + return true; } - + @Override public boolean generateVMSetupCommand(Long ssAHostId) { HostVO ssAHost = _hostDao.findById(ssAHostId); @@ -377,7 +381,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist"); return false; } - + SecStorageVMSetupCommand setupCmd = new SecStorageVMSetupCommand(); if (_allowedInternalSites != null) { List allowedCidrs = new ArrayList(); @@ -419,7 +423,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } HostVO ssAHost = _hostDao.findById(ssAHostId); SecondaryStorageVmVO thisSecStorageVm = _secStorageVmDao.findByInstanceName(ssAHost.getName()); - + if (thisSecStorageVm == null) { s_logger.warn("secondary storage VM " + ssAHost.getName() + " doesn't exist"); return false; @@ -428,7 +432,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar String copyPort = _useSSlCopy? "443" : Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT); SecStorageFirewallCfgCommand thiscpc = new SecStorageFirewallCfgCommand(true); thiscpc.addPortConfig(thisSecStorageVm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF); - + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.SecondaryStorageVM); sc.addAnd(sc.getEntity().getStatus(), Op.IN, com.cloud.host.Status.Up, com.cloud.host.Status.Connecting); @@ -449,7 +453,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar return false; } } - + SecStorageFirewallCfgCommand allSSVMIpList = new SecStorageFirewallCfgCommand(false); for (HostVO ssvm : ssvms) { if (ssvm.getId() == ssAHostId) { @@ -457,7 +461,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } allSSVMIpList.addPortConfig(ssvm.getPublicIpAddress(), copyPort, true, TemplateConstants.DEFAULT_TMPLT_COPY_INTF); } - + Answer answer = _agentMgr.easySend(ssAHostId, allSSVMIpList); if (answer != null && answer.getResult()) { if (s_logger.isDebugEnabled()) { @@ -469,7 +473,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } return false; } - + return true; } @@ -539,19 +543,19 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar DataCenterDeployment plan = new DataCenterDeployment(dataCenterId); DataCenter dc = _dcDao.findById(plan.getDataCenterId()); - + TrafficType defaultTrafficType = TrafficType.Public; if (dc.getNetworkType() == NetworkType.Basic || dc.isSecurityGroupEnabled()) { defaultTrafficType = TrafficType.Guest; } - + List defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType); - + //api should never allow this situation to happen if (defaultNetworks.size() != 1) { throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1"); } - + NetworkVO defaultNetwork = defaultNetworks.get(0); List offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork, NetworkOfferingVO.SystemStorageNetwork); @@ -570,7 +574,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } HypervisorType hypeType = _resourceMgr.getAvailableHypervisor(dataCenterId); - + VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId, hypeType); if (template == null) { s_logger.debug("Can't find a template to start"); @@ -596,7 +600,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar // for now, only one adapter is supported if(_ssVmAllocators.size() > 0) return _ssVmAllocators.get(0); - + return null; } @@ -652,8 +656,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } return; } - - + + boolean secStorageVmFromStoppedPool = false; SecondaryStorageVmVO secStorageVm = assignSecStorageVmFromStoppedPool(dataCenterId, role); if (secStorageVm == null) { @@ -798,7 +802,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } Map configs = _configDao.getConfiguration("management-server", params); - + _secStorageVmMtuSize = NumbersUtil.parseInt(configs.get("secstorage.vm.mtu.size"), DEFAULT_SS_VM_MTUSIZE); String useServiceVM = _configDao.getValue("secondary.storage.vm"); boolean _useServiceVM = false; @@ -834,7 +838,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar _agentMgr.registerForHostEvents(_listener, true, false, true); _itMgr.registerGuru(VirtualMachine.Type.SecondaryStorageVm, this); - + //check if there is a default service offering configured String ssvmSrvcOffIdStr = configs.get(Config.SecondaryStorageServiceOffering.key()); if (ssvmSrvcOffIdStr != null) { @@ -852,7 +856,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar _serviceOffering = new ServiceOfferingVO("System Offering For Secondary Storage VM", 1, ramSize, cpuFreq, null, null, false, null, _useLocalStorage, true, null, true, VirtualMachine.Type.SecondaryStorageVm, true); _serviceOffering.setUniqueName(ServiceOffering.ssvmDefaultOffUniqueName); _serviceOffering = _offeringDao.persistSystemServiceOffering(_serviceOffering); - + // this can sometimes happen, if DB is manually or programmatically manipulated if(_serviceOffering == null) { String msg = "Data integrity problem : System Offering For Secondary Storage VM has been removed?"; @@ -865,7 +869,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar _loadScanner = new SystemVmLoadScanner(this); _loadScanner.initScan(STARTUP_DELAY, _capacityScanInterval); } - + _httpProxy = configs.get(Config.SecStorageProxy.key()); if (_httpProxy != null) { boolean valid = true; @@ -989,14 +993,14 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar try { boolean result = _itMgr.expunge(ssvm, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); if (result) { - HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), + HostVO host = _hostDao.findByTypeNameAndZoneId(ssvm.getDataCenterId(), ssvm.getHostName(), Host.Type.SecondaryStorageVM); if (host != null) { s_logger.debug("Removing host entry for ssvm id=" + vmId); result = result && _hostDao.remove(host.getId()); } } - + return result; } catch (ResourceUnavailableException e) { s_logger.warn("Unable to expunge " + ssvm, e); @@ -1042,7 +1046,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar SecondaryStorageVmVO vm = profile.getVirtualMachine(); Map details = _vmDetailsDao.findDetails(vm.getId()); vm.setDetails(details); - + HostVO secHost = _ssvmMgr.findSecondaryStorageHost(dest.getDataCenter().getId()); assert (secHost != null); @@ -1081,7 +1085,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar if (externalDhcpStr != null && externalDhcpStr.equalsIgnoreCase("true")) { externalDhcp = true; } - + if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) { buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password")); } @@ -1289,7 +1293,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting, State.Stopped, State.Stopping ); int vmSize = (ssVms == null)? 0 : ssVms.size(); - List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dataCenterId); + List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dataCenterId); int hostSize = (ssHosts == null)? 0 : ssHosts.size(); if ( hostSize > vmSize ) { s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one"); @@ -1320,9 +1324,9 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar if (!(firstCmd instanceof StartupSecondaryStorageCommand)) { return null; } - + host.setType( com.cloud.host.Host.Type.SecondaryStorageVM); - return host; + return host; } @Override @@ -1368,7 +1372,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar host.setStorageUrl(ssCmd.getNfsShare()); } } - + return host; } @@ -1452,7 +1456,28 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } return null; } - + + + @Override + public HostVO pickSsvmHost(DataStore store) { + if ( store.getRole() == DataStoreRole.Image){ + Long dcId = null; + Scope storeScope = store.getScope(); + if ( storeScope.getScopeType() == ScopeType.ZONE ){ + dcId = storeScope.getScopeId(); + } + // find ssvm that can be used to download data to store. For zone-wide image store, use SSVM for that zone. For region-wide store, + // we can arbitrarily pick one ssvm to do that task + List ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId); + if (ssAHosts == null || ssAHosts.isEmpty() ) { + return null; + } + Collections.shuffle(ssAHosts); + return ssAHosts.get(0); + } + return null; + } + @Override public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, @@ -1471,6 +1496,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar @Override public void prepareStop(VirtualMachineProfile profile) { - + } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java index d315d22cdd6..8565c38cc08 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java @@ -18,6 +18,8 @@ package com.cloud.storage.secondary; import java.util.List; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; + import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.host.HostVO; @@ -29,12 +31,12 @@ public interface SecondaryStorageVmManager extends Manager { public static final int DEFAULT_SS_VM_RAMSIZE = 256; // 256M public static final int DEFAULT_SS_VM_CPUMHZ = 500; // 500 MHz - public static final int DEFAULT_SS_VM_MTUSIZE = 1500; + public static final int DEFAULT_SS_VM_MTUSIZE = 1500; public static final int DEFAULT_SS_VM_CAPACITY = 50; // max command execution session per SSVM public static final int DEFAULT_STANDBY_CAPACITY = 10; // standy capacity to reserve per zone - + public static final String ALERT_SUBJECT = "secondarystoragevm-alert"; - + public SecondaryStorageVmVO startSecStorageVm(long ssVmVmId); public boolean stopSecStorageVm(long ssVmVmId); public boolean rebootSecStorageVm(long ssVmVmId); @@ -42,7 +44,7 @@ public interface SecondaryStorageVmManager extends Manager { public void onAgentConnect(Long dcId, StartupCommand cmd); public boolean generateFirewallConfiguration(Long agentId); public boolean generateVMSetupCommand(Long hostId); - + public Pair assignSecStorageVm(long zoneId, Command cmd); boolean generateSetupCommand(Long hostId); boolean deleteHost(Long hostId); @@ -53,4 +55,5 @@ public interface SecondaryStorageVmManager extends Manager { public List listAllTypesSecondaryStorageHostsInOneZone(long dataCenterId); public List listUpAndConnectingSecondaryStorageVmHost(Long dcId); public HostVO pickSsvmHost(HostVO ssHost); + public HostVO pickSsvmHost(DataStore store); } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 491900b44e6..709288eca00 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -37,6 +37,7 @@ 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.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.log4j.Logger; @@ -50,6 +51,7 @@ import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; +import com.cloud.storage.ScopeType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.TemplateProfile; @@ -81,7 +83,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te public String getName() { return TemplateAdapterType.Hypervisor.getName(); } - + private String validateUrl(String url) { try { URI uri = new URI(url); @@ -164,23 +166,30 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te @Override public VMTemplateVO create(TemplateProfile profile) { + // persist entry in vm_template, vm_template_details and template_zone_ref tables VMTemplateVO template = persistTemplate(profile); if (template == null) { throw new CloudRuntimeException("Unable to persist the template " + profile.getTemplate()); } - DataStore imageStore = this.storeMgr.getDataStore(profile.getImageStoreId(), DataStoreRole.Image); - - AsyncCallFuture future = this.imageService.createTemplateAsync(this.imageFactory.getTemplate(template.getId()), imageStore); - try { - future.get(); - } catch (InterruptedException e) { - s_logger.debug("create template Failed", e); - throw new CloudRuntimeException("create template Failed", e); - } catch (ExecutionException e) { - s_logger.debug("create template Failed", e); - throw new CloudRuntimeException("create template Failed", e); + // find all eligible image stores for this zone scope + List imageStores = this.storeMgr.getImageStoresByScope(new ZoneScope(profile.getZoneId())); + if ( imageStores == null || imageStores.size() == 0 ){ + throw new CloudRuntimeException("Unable to find image store to download template "+ profile.getTemplate()); + } + for (DataStore imageStore : imageStores) { + AsyncCallFuture future = this.imageService + .createTemplateAsync(this.imageFactory.getTemplate(template.getId()), imageStore); + try { + future.get(); + } catch (InterruptedException e) { + s_logger.debug("create template Failed", e); + throw new CloudRuntimeException("create template Failed", e); + } catch (ExecutionException e) { + s_logger.debug("create template Failed", e); + throw new CloudRuntimeException("create template Failed", e); + } } _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage, diff --git a/server/src/com/cloud/template/TemplateAdapter.java b/server/src/com/cloud/template/TemplateAdapter.java index 1f8f491cb25..766afa85c7d 100755 --- a/server/src/com/cloud/template/TemplateAdapter.java +++ b/server/src/com/cloud/template/TemplateAdapter.java @@ -33,19 +33,19 @@ import com.cloud.utils.component.Adapter; public interface TemplateAdapter extends Adapter { public static class TemplateAdapterType { String _name; - + public static final TemplateAdapterType Hypervisor = new TemplateAdapterType("HypervisorAdapter"); public static final TemplateAdapterType BareMetal = new TemplateAdapterType("BareMetalAdapter"); - + public TemplateAdapterType(String name) { _name = name; } - + public String getName() { return _name; } } - + public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException; public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException; @@ -57,14 +57,14 @@ public interface TemplateAdapter extends Adapter { public TemplateProfile prepareDelete(DeleteIsoCmd cmd); public boolean delete(TemplateProfile profile); - + public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException; - + public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, - String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshKeyEnabled, String imageStoreUuid) throws ResourceAllocationException; + String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshKeyEnabled) throws ResourceAllocationException; } diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 1b114250621..1e79b60f150 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -82,12 +82,12 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat protected @Inject ResourceLimitService _resourceLimitMgr; protected @Inject DataStoreManager storeMgr; @Inject TemplateManager templateMgr; - + @Override public boolean stop() { return true; } - + private static boolean isAdmin(short accountType) { return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || @@ -100,34 +100,24 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException { return prepare(isIso, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, featured, isExtractable, format, guestOSId, zoneId, hypervisorType, - chksum, bootable, null, null, details, false, null); + chksum, bootable, null, null, details, false); } - + public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, - String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled, - String imageStoreUuid) throws ResourceAllocationException { - //Long accountId = null; + String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled) throws ResourceAllocationException { + // parameters verification - - String storeUuid = imageStoreUuid; - if (storeUuid != null) { - DataStore store = this.storeMgr.getDataStore(storeUuid, DataStoreRole.Image); - if (store == null) { - throw new InvalidParameterValueException("invalide image store uuid" + storeUuid); - } - - } - + if (isPublic == null) { isPublic = Boolean.FALSE; } - + if (zoneId.longValue() == -1) { zoneId = null; } - + if (isIso) { if (bootable == null) { bootable = Boolean.TRUE; @@ -148,9 +138,9 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat } if (requiresHVM == null) { requiresHVM = true; - } + } } - + if (isExtractable == null) { isExtractable = Boolean.FALSE; } @@ -167,7 +157,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat if (url.toLowerCase().contains("file://")) { throw new InvalidParameterValueException("File:// type urls are currently unsupported"); } - + boolean allowPublicUserTemplates = Boolean.parseBoolean(_configDao.getValue("allow.public.user.templates")); if (!isAdmin && !allowPublicUserTemplates && isPublic) { throw new InvalidParameterValueException("Only private templates/ISO can be created."); @@ -176,24 +166,24 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat if (!isAdmin || featured == null) { featured = Boolean.FALSE; } - + ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase()); if (imgfmt == null) { throw new IllegalArgumentException("Image format is incorrect " + format + ". Supported formats are " + EnumUtils.listValues(ImageFormat.values())); } - + // Check that the resource limit for templates/ISOs won't be exceeded UserVO user = _userDao.findById(userId); if (user == null) { throw new IllegalArgumentException("Unable to find user with id " + userId); } - + _resourceLimitMgr.checkResourceLimit(templateOwner, ResourceType.template); - + if (templateOwner.getType() != Account.ACCOUNT_TYPE_ADMIN && zoneId == null) { throw new IllegalArgumentException("Only admins can create templates in all zones"); } - + // If a zoneId is specified, make sure it is valid if (zoneId != null) { DataCenterVO zone = _dcDao.findById(zoneId); @@ -205,39 +195,33 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: "+ zoneId ); } } - + List systemvmTmplts = _tmpltDao.listAllSystemVMTemplates(); for (VMTemplateVO template : systemvmTmplts) { if (template.getName().equalsIgnoreCase(name) || template.getDisplayText().equalsIgnoreCase(displayText)) { throw new IllegalArgumentException("Cannot use reserved names for templates"); } } - - DataStore imageStore = this.templateMgr.getImageStore(imageStoreUuid, zoneId); - if (imageStore == null) { - throw new IllegalArgumentException("Cann't find an image store"); - } - Long imageStoreId = imageStore.getId(); - + Long id = _tmpltDao.getNextInSequence(Long.class, "id"); UserContext.current().setEventDetails("Id: " +id+ " name: " + name); return new TemplateProfile(id, userId, name, displayText, bits, passwordEnabled, requiresHVM, url, isPublic, - featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled, imageStoreId); + featured, isExtractable, imgfmt, guestOSId, zoneId, hypervisorType, templateOwner.getAccountName(), templateOwner.getDomainId(), templateOwner.getAccountId(), chksum, bootable, templateTag, details, sshkeyEnabled); } - + @Override public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocationException { //check if the caller can operate with the template owner Account caller = UserContext.current().getCaller(); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); _accountMgr.checkAccess(caller, null, true, owner); - - + + return prepare(false, UserContext.current().getCallerUserId(), cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), cmd.isPasswordEnabled(), cmd.getRequiresHvm(), cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), cmd.getFormat(), cmd.getOsTypeId(), cmd.getZoneId(), HypervisorType.getType(cmd.getHypervisor()), - cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled(), cmd.getImageStoreUuid()); + cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled()); } public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { @@ -245,24 +229,23 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat Account caller = UserContext.current().getCaller(); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); _accountMgr.checkAccess(caller, null, true, owner); - + return prepare(true, UserContext.current().getCallerUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false, true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), - cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false, cmd.getImageStoreUuid()); + cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false); } - + protected VMTemplateVO persistTemplate(TemplateProfile profile) { Long zoneId = profile.getZoneId(); VMTemplateVO template = new VMTemplateVO(profile.getTemplateId(), profile.getName(), profile.getFormat(), profile.getIsPublic(), profile.getFeatured(), profile.getIsExtractable(), TemplateType.USER, profile.getUrl(), profile.getRequiresHVM(), profile.getBits(), profile.getAccountId(), profile.getCheckSum(), profile.getDisplayText(), - profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag(), + profile.getPasswordEnabled(), profile.getGuestOsId(), profile.getBootable(), profile.getHypervisorType(), profile.getTemplateTag(), profile.getDetails(), profile.getSshKeyEnabled()); - template.setImageDataStoreId(profile.getImageStoreId()); if (zoneId == null || zoneId.longValue() == -1) { List dcs = _dcDao.listAll(); - + if (dcs.isEmpty()) { throw new CloudRuntimeException("No zones are present in the system, can't add template"); } @@ -271,13 +254,13 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat for (DataCenterVO dc: dcs) { _tmpltDao.addTemplateToZone(template, dc.getId()); } - + } else { _tmpltDao.addTemplateToZone(template, zoneId); } return _tmpltDao.findById(template.getId()); } - + private Long accountAndUserValidation(Account account, long userId, UserVmVO vmInstanceCheck, VMTemplateVO template, String msg) throws PermissionDeniedException { @@ -311,7 +294,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat return userId; } - + public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { Long templateId = cmd.getId(); Long userId = UserContext.current().getCallerUserId(); @@ -342,23 +325,23 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat Long userId = UserContext.current().getCallerUserId(); Account account = UserContext.current().getCaller(); Long zoneId = cmd.getZoneId(); - + VMTemplateVO template = _tmpltDao.findById(templateId.longValue()); if (template == null) { throw new InvalidParameterValueException("unable to find iso with id " + templateId); } - + userId = accountAndUserValidation(account, userId, null, template, "Unable to delete iso " ); - + UserVO user = _userDao.findById(userId); if (user == null) { throw new InvalidParameterValueException("Please specify a valid user."); } - + if (template.getFormat() != ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid iso."); } - + return new TemplateProfile(userId, template, zoneId); } From dcbeea057bf9096ca8bc51a9540a493898728922 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 11 Apr 2013 10:20:58 -0700 Subject: [PATCH 016/303] Extract a common routine to associate template to zones in template_zone_ref table. --- .../storage/download/DownloadMonitorImpl.java | 67 ++++++++----------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 70254def3f9..82665e361a1 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -922,26 +922,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor tmpltStore.setSize(tmpltInfo.getSize()); tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); _vmTemplateStoreDao.persist(tmpltStore); - List dcs = new ArrayList(); - if (zoneId != null ){ - dcs.add(zoneId); - } - else{ - List zones = _dcDao.listAll(); - for (DataCenterVO zone : zones){ - dcs.add(zone.getId()); - } - } - for (Long id : dcs) { - VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, tmplt.getId()); - if (tmpltZoneVO == null) { - tmpltZoneVO = new VMTemplateZoneVO(id, tmplt.getId(), new Date()); - _vmTemplateZoneDao.persist(tmpltZoneVO); - } else { - tmpltZoneVO.setLastUpdated(new Date()); - _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); - } - } + this.associateTemplateToZone(tmplt.getId(), zoneId); } continue; @@ -953,26 +934,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly"); TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); _vmTemplateStoreDao.persist(templtStore); - List dcs = new ArrayList(); - if (zoneId != null ){ - dcs.add(zoneId); - } - else{ - List zones = _dcDao.listAll(); - for (DataCenterVO zone : zones){ - dcs.add(zone.getId()); - } - } - for (Long id : dcs) { - VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, tmplt.getId()); - if (tmpltZoneVO == null) { - tmpltZoneVO = new VMTemplateZoneVO(id, tmplt.getId(), new Date()); - _vmTemplateZoneDao.persist(tmpltZoneVO); - } else { - tmpltZoneVO.setLastUpdated(new Date()); - _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); - } - } + this.associateTemplateToZone(tmplt.getId(), zoneId); } } @@ -1105,5 +1067,30 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } + // persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case, + // we will associate the template to all the zones. + private void associateTemplateToZone(long templateId, Long zoneId){ + List dcs = new ArrayList(); + if (zoneId != null ){ + dcs.add(zoneId); + } + else{ + List zones = _dcDao.listAll(); + for (DataCenterVO zone : zones){ + dcs.add(zone.getId()); + } + } + for (Long id : dcs) { + VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId); + if (tmpltZoneVO == null) { + tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date()); + _vmTemplateZoneDao.persist(tmpltZoneVO); + } else { + tmpltZoneVO.setLastUpdated(new Date()); + _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); + } + } + } + } From e5bf38ed051df248e5aaa5e362679fbaf368d2e0 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 10 Apr 2013 23:36:39 -0700 Subject: [PATCH 017/303] add cache storage --- api/src/com/cloud/storage/StorageService.java | 3 + .../admin/storage/CreateCacheStoreCmd.java | 123 +++++++++++++++ .../api/storage}/DataMotionService.java | 4 +- .../api/storage}/DataMotionStrategy.java | 4 +- .../api/storage/DataStoreManager.java | 1 + .../api/storage/DataStoreProvider.java | 3 +- .../api/storage/DataStoreProviderManager.java | 1 + .../api/storage/StorageCacheManager.java} | 7 +- .../storage/datastore/db/ImageStoreVO.java | 14 ++ engine/pom.xml | 4 +- .../storage/backup/BackupService.java | 26 ---- engine/storage/{backup => cache}/pom.xml | 4 +- .../allocator/StorageCacheAllocator.java} | 8 +- .../StorageCacheRandomAllocator.java | 51 +++++++ .../manager/StorageCacheManagerImpl.java | 100 +++++++++++++ .../{imagemotion => datamotion}/pom.xml | 4 +- .../motion/AncientDataMotionStrategy.java | 1 + .../storage/motion/DataMotionDriver.java | 0 .../storage/motion/DataMotionServiceImpl.java | 2 + .../ImageStoreProviderManagerImpl.java | 24 +++ .../motion/DefaultImageMotionStrategy.java | 140 ------------------ .../image/motion/ImageMotionServiceImpl.java | 70 --------- .../test/MockStorageMotionStrategy.java | 2 +- .../strategy/AncientSnapshotStrategy.java | 13 +- .../datastore/DataObjectManagerImpl.java | 2 +- .../datastore/DataStoreManagerImpl.java | 7 +- .../ObjectInDataStoreManagerImpl.java | 4 - .../DataStoreProviderManagerImpl.java | 27 +++- .../image/datastore/ImageStoreHelper.java | 3 + .../datastore/ImageStoreProviderManager.java | 1 + .../volume/TemplateInstallStrategyImpl.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 3 +- .../CloudStackImageStoreProviderImpl.java | 1 + .../com/cloud/storage/StorageManagerImpl.java | 70 +++++++++ tools/apidoc/gen_toc.py | 1 + 35 files changed, 450 insertions(+), 280 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/command/admin/storage/CreateCacheStoreCmd.java rename engine/{storage/src/org/apache/cloudstack/storage/motion => api/src/org/apache/cloudstack/engine/subsystem/api/storage}/DataMotionService.java (84%) rename engine/{storage/src/org/apache/cloudstack/storage/motion => api/src/org/apache/cloudstack/engine/subsystem/api/storage}/DataMotionStrategy.java (85%) rename engine/{storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java => api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java} (83%) delete mode 100644 engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupService.java rename engine/storage/{backup => cache}/pom.xml (94%) rename engine/storage/{imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java => cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java} (74%) create mode 100644 engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheRandomAllocator.java create mode 100644 engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheManagerImpl.java rename engine/storage/{imagemotion => datamotion}/pom.xml (95%) rename engine/storage/{ => datamotion}/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java (99%) rename engine/storage/{ => datamotion}/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java (100%) rename engine/storage/{ => datamotion}/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java (93%) delete mode 100644 engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java delete mode 100644 engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java diff --git a/api/src/com/cloud/storage/StorageService.java b/api/src/com/cloud/storage/StorageService.java index ee1a9565be4..869b2960e1c 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 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 00000000000..ff01a40c1fa --- /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 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 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()); + } + } +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java similarity index 84% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java index db36f6492e8..adeeecbeed3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionService.java @@ -16,10 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; public interface DataMotionService { diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java similarity index 85% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java index ba40c6dcbce..e2cc2a06211 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMotionStrategy.java @@ -16,10 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; public interface DataMotionStrategy { 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 def3b96d331..1a36c8ca45d 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 getImageStoresByScope(ZoneScope scope); public List getImageStoresByProvider(String provider); + public List getImageCacheStores(Scope scope); public DataStore registerDataStore(Map params, String providerUuid); } 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 083c7d39b67..c0c1f76a30f 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(); 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 8dd8c3a0824..6872bdfc726 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 getDataStoreProviders(); } diff --git a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java similarity index 83% rename from engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java index cb49027f3bf..0fdec110661 100644 --- a/engine/storage/backup/src/org/apache/cloudstack/storage/backup/BackupMotionService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageCacheManager.java @@ -16,8 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.backup; +package org.apache.cloudstack.engine.subsystem.api.storage; -public interface BackupMotionService { - boolean copySnapshot(String snapshotUri, String destSnapshotUri); + +public interface StorageCacheManager { + public DataStore getCacheStorage(Scope scope); } 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 7f950362fd8..5503df069dd 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; diff --git a/engine/pom.xml b/engine/pom.xml index 1a3d896d50d..3b686f2399e 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -39,8 +39,8 @@ storage storage/volume storage/image - storage/imagemotion - storage/backup + storage/datamotion + storage/cache storage/snapshot storage/integration-test components-api 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 67924d2ce73..00000000000 --- 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); -} diff --git a/engine/storage/backup/pom.xml b/engine/storage/cache/pom.xml similarity index 94% rename from engine/storage/backup/pom.xml rename to engine/storage/cache/pom.xml index 019e09c7204..f00f6cd1498 100644 --- a/engine/storage/backup/pom.xml +++ b/engine/storage/cache/pom.xml @@ -11,8 +11,8 @@ 4.0.0 - cloud-engine-storage-backup - Apache CloudStack Engine Storage Backup Component + cloud-engine-storage-cache + Apache CloudStack Engine Storage Cache Component org.apache.cloudstack cloud-engine diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java similarity index 74% rename from engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java rename to engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java index 7a476367d37..4259d9ed03f 100644 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionStrategy.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/allocator/StorageCacheAllocator.java @@ -16,9 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.image.motion; +package org.apache.cloudstack.storage.cache.allocator; -import org.apache.cloudstack.storage.motion.DataMotionStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -public interface ImageMotionStrategy extends DataMotionStrategy { +public interface StorageCacheAllocator { + DataStore getCacheStore(Scope scope); } 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 00000000000..c357d239026 --- /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 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); + } +} 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 00000000000..c85565d8266 --- /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; + @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 params) { + // TODO Auto-generated method stub + + } + + @Override + public Map 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 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 diff --git a/engine/storage/imagemotion/pom.xml b/engine/storage/datamotion/pom.xml similarity index 95% rename from engine/storage/imagemotion/pom.xml rename to engine/storage/datamotion/pom.xml index 9a7f3e017a2..8a3698c94d3 100644 --- a/engine/storage/imagemotion/pom.xml +++ b/engine/storage/datamotion/pom.xml @@ -11,8 +11,8 @@ 4.0.0 - cloud-engine-storage-imagemotion - Apache CloudStack Engine Storage Image Motion Component + cloud-engine-storage-datamotion + Apache CloudStack Engine Storage Data Motion Component org.apache.cloudstack cloud-engine diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java similarity index 99% rename from engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java rename to engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 3602bb16baf..1d164cdddf7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -24,6 +24,7 @@ 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; diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java rename to engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java similarity index 93% rename from engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java rename to engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java index 343140fb98e..93ab4124fcd 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java @@ -23,6 +23,8 @@ 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; 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 dbcfb765e1d..a1096d31fad 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 listImageCacheStores(Scope scope) { + List imageStores = new ArrayList(); + if (scope.getScopeType() != ScopeType.ZONE) { + s_logger.debug("only support zone wide image cache stores"); + return imageStores; + } + SearchCriteriaService 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 cacheStores = sc.list(); + for (ImageStoreVO store : cacheStores) { + imageStores.add(getImageStore(store.getId())); + } + return imageStores; + } } diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java deleted file mode 100644 index c49a521a3ca..00000000000 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/DefaultImageMotionStrategy.java +++ /dev/null @@ -1,140 +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.image.motion; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.command.CopyCmd; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; -import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; - -import com.cloud.agent.api.Answer; - -//At least one of datastore is coming from image store or image cache store - -public class DefaultImageMotionStrategy implements ImageMotionStrategy { - @Inject - EndPointSelector selector; - private class CreateTemplateContext extends AsyncRpcConext { - private final TemplateOnPrimaryDataStoreInfo template; - public CreateTemplateContext(AsyncCompletionCallback callback, TemplateOnPrimaryDataStoreInfo template) { - super(callback); - this.template = template; - } - - public TemplateOnPrimaryDataStoreInfo getTemplate() { - return this.template; - } - - } -/* - @Override - public void copyTemplateAsync(String destUri, String srcUri, EndPoint ep, AsyncCompletionCallback callback) { - - CopyCmd copyCommand = new CopyCmd(destUri, srcUri); - CreateTemplateContext context = new CreateTemplateContext(callback, null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null)) - .setContext(context); - - ep.sendMessageAsync(copyCommand, caller); - } - - public Object copyTemplateCallBack(AsyncCallbackDispatcher callback, CreateTemplateContext context) { - AsyncCompletionCallback parentCall = context.getParentCallback(); - CopyTemplateToPrimaryStorageAnswer answer = (CopyTemplateToPrimaryStorageAnswer)callback.getResult(); - CommandResult result = new CommandResult(); - - if (!answer.getResult()) { - result.setSucess(answer.getResult()); - result.setResult(answer.getDetails()); - } else { - TemplateOnPrimaryDataStoreInfo templateStore = context.getTemplate(); - templateStore.setPath(answer.getPath()); - result.setSucess(true); - } - - parentCall.complete(result); - return null; - }*/ - - @Override - public boolean canHandle(DataObject srcData, DataObject destData) { - /* - DataStore destStore = destData.getDataStore(); - DataStore srcStore = srcData.getDataStore(); - if (destStore.getRole() == DataStoreRole.Image || destStore.getRole() == DataStoreRole.ImageCache - || srcStore.getRole() == DataStoreRole.Image - || srcStore.getRole() == DataStoreRole.ImageCache) { - return true; - }*/ - return false; - } - - @Override - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { - DataStore destStore = destData.getDataStore(); - DataStore srcStore = srcData.getDataStore(); - EndPoint ep = selector.select(srcData, destData); - CopyCommandResult result = new CopyCommandResult("", null); - if (ep == null) { - result.setResult("can't find end point"); - callback.complete(result); - return null; - } - - String srcUri = srcStore.getDriver().grantAccess(srcData, ep); - String destUri = destStore.getDriver().grantAccess(destData, ep); - CopyCmd cmd = new CopyCmd(srcUri, destUri); - - CreateTemplateContext context = new CreateTemplateContext(callback, null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyAsyncCallback(null, null)) - .setContext(context); - - ep.sendMessageAsync(cmd, caller); - return null; - } - - protected Void copyAsyncCallback(AsyncCallbackDispatcher callback, CreateTemplateContext context) { - AsyncCompletionCallback parentCall = context.getParentCallback(); - Answer answer = (Answer)callback.getResult(); - if (!answer.getResult()) { - CopyCommandResult result = new CopyCommandResult("", null); - result.setResult(answer.getDetails()); - parentCall.complete(result); - } else { - CopyCmdAnswer ans = (CopyCmdAnswer)answer; - CopyCommandResult result = new CopyCommandResult(ans.getPath(), null); - parentCall.complete(result); - } - return null; - - } - -} diff --git a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java b/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java deleted file mode 100644 index 93ba4a5ad64..00000000000 --- a/engine/storage/imagemotion/src/org/apache/cloudstack/storage/image/motion/ImageMotionServiceImpl.java +++ /dev/null @@ -1,70 +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.image.motion; - -import java.util.List; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - - -public class ImageMotionServiceImpl implements ImageMotionService { - @Inject - List motionStrategies; - @Inject - VolumeService volumeService; - @Inject - ImageService imageService; - - @Override - public boolean copyIso(String isoUri, String destIsoUri) { - // TODO Auto-generated method stub - return false; - } - - - - @Override - public void copyTemplateAsync(TemplateInfo destTemplate, TemplateInfo srcTemplate, AsyncCompletionCallback callback) { - /* ImageMotionStrategy ims = null; - for (ImageMotionStrategy strategy : motionStrategies) { - if (strategy.canHandle(srcTemplate)) { - ims = strategy; - break; - } - } - - if (ims == null) { - throw new CloudRuntimeException("Can't find proper image motion strategy"); - } - - EndPoint ep = ims.getEndPoint(destTemplate, srcTemplate); - String srcUri = srcTemplate.getDataStore().grantAccess(srcTemplate, ep); - String destUri = destTemplate.getDataStore().grantAccess(destTemplate, ep); - - ims.copyTemplateAsync(destUri, srcUri, ep, callback);*/ - } - - -} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java index b619ee9240f..53051314122 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java @@ -19,9 +19,9 @@ package org.apache.cloudstack.storage.test; 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.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.motion.DataMotionStrategy; public class MockStorageMotionStrategy implements DataMotionStrategy { diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java index 3863481fb90..7eddb34943d 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java @@ -25,7 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -45,23 +45,15 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.cloudstack.storage.snapshot.SnapshotStateMachineManager; 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.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; -import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -73,12 +65,9 @@ import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.s3.S3Manager; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.swift.SwiftManager; 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.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java index 218f9013a17..566da62389e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -31,7 +32,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index eb233aa3f8b..adc7250cc73 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -46,6 +46,8 @@ public class DataStoreManagerImpl implements DataStoreManager { return primaryStorMgr.getPrimaryDataStore(storeId); } else if (role == DataStoreRole.Image) { return imageDataStoreMgr.getImageStore(storeId); + } else if (role == DataStoreRole.ImageCache) { + return imageDataStoreMgr.getImageStore(storeId); } throw new CloudRuntimeException("un recognized type" + role); } @@ -81,5 +83,8 @@ public class DataStoreManagerImpl implements DataStoreManager { public DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); } - + @Override + public List getImageCacheStores(Scope scope) { + return imageDataStoreMgr.listImageCacheStores(scope); + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 80badc54d30..9f98d5d518d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -161,11 +161,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { this.stateMachines.transitTo(obj, event, null, templatePoolDao); } catch (NoTransitionException e) { - if (event == Event.CreateOnlyRequested || event == Event.OperationSuccessed) { - s_logger.debug("allow muliple create requests"); - } else { throw e; - } } } else { throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index b7ed53dfcf6..e34a35ef2c1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -34,8 +34,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; -import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; +import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -68,7 +68,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public List getPrimaryDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { - if (provider instanceof PrimaryDataStoreProvider) { + if (provider.getTypes().contains(DataStoreProviderType.PRIMARY)) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.PRIMARY.toString()); @@ -81,7 +81,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public List getImageDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { - if (provider instanceof ImageStoreProvider) { + if (provider.getTypes().contains(DataStoreProviderType.IMAGE)) { StorageProviderResponse response = new StorageProviderResponse(); response.setName(provider.getName()); response.setType(DataStoreProvider.DataStoreProviderType.IMAGE.toString()); @@ -90,6 +90,19 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } return providers; } + + public List getCacheDataStoreProviders() { + List providers = new ArrayList(); + for (DataStoreProvider provider : providerMap.values()) { + if (provider.getTypes().contains(DataStoreProviderType.ImageCache)) { + StorageProviderResponse response = new StorageProviderResponse(); + response.setName(provider.getName()); + response.setType(DataStoreProviderType.ImageCache.toString()); + providers.add(response); + } + } + return providers; + } @Override public boolean configure(String name, Map params) @@ -125,6 +138,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } catch(Exception e) { s_logger.debug("configure provider failed", e); providerMap.remove(providerName); + return false; } } @@ -141,6 +155,11 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto public DataStoreProvider getDefaultImageDataStoreProvider() { return this.getDataStoreProvider("CloudStack ImageStore Provider"); } + + @Override + public DataStoreProvider getDefaultCacheDataStoreProvider() { + return this.getDataStoreProvider("cloudstack image store provider"); + } @Override public List getDataStoreProviders(String type) { @@ -151,6 +170,8 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return this.getPrimaryDataStoreProviders(); } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.IMAGE.toString())) { return this.getImageDataStoreProviders(); + } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.ImageCache.toString())) { + return this.getCacheDataStoreProviders(); } else { throw new InvalidParameterValueException("Invalid parameter: " + type); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index 33fda486c36..a4d3db93718 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -23,6 +23,7 @@ import java.util.Map; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; @@ -52,6 +53,7 @@ public class ImageStoreHelper { store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); + store.setRole(DataStoreRole.getRole((String)params.get("role"))); store = imageStoreDao.persist(store); return store; } @@ -68,6 +70,7 @@ public class ImageStoreHelper { store.setScope((ScopeType)params.get("scope")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); + store.setRole(DataStoreRole.getRole((String)params.get("role"))); store = imageStoreDao.persist(store); // persist details diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index 2026346ccdc..f8fa28176a0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -31,5 +31,6 @@ public interface ImageStoreProviderManager { List listImageStores(); List listImageStoresByScope(ZoneScope scope); List listImageStoreByProvider(String provider); + List listImageCacheStores(Scope scope); boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java index 5f1735c180a..69979e5a16a 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java @@ -20,12 +20,12 @@ package org.apache.cloudstack.storage.volume; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.cloudstack.storage.volume.VolumeServiceImpl.CreateBaseImageResult; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 32e7d274f01..ff504ebe0e9 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; @@ -40,7 +41,6 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; -import org.apache.cloudstack.storage.motion.DataMotionService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -52,7 +52,6 @@ import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.utils.db.DB; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index e025cf4de4a..fdeba4d7c73 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -83,6 +83,7 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { public Set getTypes() { Set types = new HashSet(); types.add(DataStoreProviderType.IMAGE); + types.add(DataStoreProviderType.ImageCache); return types; } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 77249680170..78b26bb69fd 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -42,6 +42,7 @@ import javax.naming.ConfigurationException; 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; @@ -1966,6 +1967,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C params.put("details", details); params.put("scope", scopeType); params.put("providerName", storeProvider.getName()); + params.put("role", DataStoreRole.Image); DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); DataStore store = null; @@ -2017,6 +2019,74 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C txn.commit(); return true; } + @Override + public ImageStore createCacheStore(CreateCacheStoreCmd cmd) { + String providerName = cmd.getProviderName(); + DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); + + if (storeProvider == null) { + storeProvider = _dataStoreProviderMgr.getDefaultCacheDataStoreProvider(); + if (storeProvider == null) { + throw new InvalidParameterValueException("can't find cache store provider: " + providerName); + } + } + + Long dcId = cmd.getZoneId(); + + ScopeType scopeType = null; + String scope = cmd.getScope(); + if (scope != null) { + try { + scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); + + } catch (Exception e) { + throw new InvalidParameterValueException("invalid scope" + scope); + } + + if (scopeType != ScopeType.ZONE) { + throw new InvalidParameterValueException("Only zone wide cache storage is supported"); + } + } + + if (scopeType == ScopeType.ZONE && dcId == null) { + throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); + } + + + // Check if the zone exists in the system + DataCenterVO zone = _dcDao.findById(dcId); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + dcId); + } + + Account account = UserContext.current().getCaller(); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + PermissionDeniedException ex = new PermissionDeniedException( + "Cannot perform this operation, Zone with specified id is currently disabled"); + ex.addProxyObject(zone, dcId, "dcId"); + throw ex; + } + + Map params = new HashMap(); + params.put("zoneId", dcId); + params.put("url", cmd.getUrl()); + params.put("name", cmd.getUrl()); + params.put("details", cmd.getDetails()); + params.put("scope", scopeType); + params.put("providerName", storeProvider.getName()); + params.put("role", DataStoreRole.ImageCache); + + DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); + DataStore store = null; + try { + store = lifeCycle.initialize(params); + } catch (Exception e) { + s_logger.debug("Failed to add data store", e); + throw new CloudRuntimeException("Failed to add data store", e); + } + + return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache); + } } diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index ab2456dd3eb..e41e883066a 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -95,6 +95,7 @@ known_categories = { 'InstanceGroup': 'VM Group', 'StorageMaintenance': 'Storage Pool', 'StoragePool': 'Storage Pool', + 'CacheStore': 'Storage Pool', 'StorageProvider': 'Storage Pool', 'SecurityGroup': 'Security Group', 'SSH': 'SSH', From 1c448cd6e3bde8f9cff63f652d592a9ff7f7c8f7 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 11 Apr 2013 11:01:29 -0700 Subject: [PATCH 018/303] add cache storage --- .../api/storage/StorageCacheManager.java | 1 + .../manager/StorageCacheManagerImpl.java | 14 +++++++ .../snapshot/SnapshotDataFactoryImpl.java | 2 +- .../strategy/AncientSnapshotStrategy.java | 2 +- .../datastore/ObjectInDataStoreManager.java | 2 +- .../ObjectInDataStoreManagerImpl.java | 23 +++++++++-- .../storage/db/ObjectInDataStoreVO.java | 32 +++++++-------- .../storage/volume/VolumeDataFactoryImpl.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 40 ++++++++++++++++++- 9 files changed, 93 insertions(+), 25 deletions(-) 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 index 0fdec110661..70332c70db8 100644 --- 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 @@ -21,4 +21,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface StorageCacheManager { public DataStore getCacheStorage(Scope scope); + public DataObject createCacheObject(DataObject data, Scope scope); } 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 index c85565d8266..f943ed49f82 100644 --- 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 @@ -24,6 +24,8 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; @@ -34,6 +36,8 @@ import com.cloud.utils.component.Manager; public class StorageCacheManagerImpl implements StorageCacheManager, Manager { @Inject List storageCacheAllocator; + @Inject + DataMotionService dataMotionSvr; @Override public DataStore getCacheStorage(Scope scope) { for (StorageCacheAllocator allocator : storageCacheAllocator) { @@ -97,4 +101,14 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { // TODO Auto-generated method stub return true; } + + @Override + public DataObject createCacheObject(DataObject data, Scope scope) { + DataStore cacheStore = this.getCacheStorage(scope); + DataObject objOnCacheStore = cacheStore.create(data); + //AsyncCallFuture<> + //dataMotionSvr.copyAsync(data, objOnCacheStore, callback); + // TODO Auto-generated method stub + return null; + } } \ No newline at end of file diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java index 0bd40d35122..6a7edc2302c 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java @@ -63,7 +63,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId); SnapshotObject so = null; if (snapshot.getState() == Snapshot.State.BackedUp) { - DataStore store = objMap.findStore(snapshot.getUuid(), DataObjectType.SNAPSHOT, DataStoreRole.Image); + DataStore store = objMap.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image); so = SnapshotObject.getSnapshotObject(snapshot, store); } else { VolumeInfo volume = this.volumeFactory.getVolume(snapshot.getVolumeId()); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java index 7eddb34943d..ce2786b80b9 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java @@ -470,7 +470,7 @@ public class AncientSnapshotStrategy implements SnapshotStrategy { @DB protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { - DataStore store = objInStoreMgr.findStore(snapshot.getUuid(), DataObjectType.SNAPSHOT, DataStoreRole.Image); + DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image); if (store == null) { s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); return false; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index 17b782ab6a0..cb27c0271c9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -32,5 +32,5 @@ public interface ObjectInDataStoreManager { DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role); DataObjectInStore findObject(DataObject obj, DataStore store); - DataStore findStore(String objUuid, DataObjectType type, DataStoreRole role); + DataStore findStore(long objId, DataObjectType type, DataStoreRole role); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 9f98d5d518d..ac96c5f9f69 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -35,6 +35,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.cloudstack.storage.db.ObjectInDataStoreDao; import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -69,6 +70,8 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { VMTemplatePoolDao templatePoolDao; @Inject SnapshotDataFactory snapshotFactory; + @Inject + ObjectInDataStoreDao objInStoreDao; protected StateMachine2 stateMachines; public ObjectInDataStoreManagerImpl() { @@ -110,6 +113,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); vo = templatePoolDao.persist(vo); } + } else if (dataStore.getRole() == DataStoreRole.ImageCache) { + ObjectInDataStoreVO vo = new ObjectInDataStoreVO(); + vo.setDataStoreRole(dataStore.getRole()); + vo.setDataStoreId(dataStore.getId()); + vo.setObjectType(obj.getType()); + vo.setObjectId(obj.getId()); + vo = objInStoreDao.persist(vo); } else { // Image store switch ( obj.getType()){ @@ -212,6 +222,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); + } else if (role == DataStoreRole.ImageCache) { + SearchCriteriaService sc = SearchCriteria2.create(ObjectInDataStoreVO.class); + sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId); + sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type); + sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, dataStoreId); + sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role); + vo = sc.find(); } else { s_logger.debug("Invalid data or store type: " + type + " " + role); throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role); @@ -222,16 +239,16 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } @Override - public DataStore findStore(String objUuid, DataObjectType type, DataStoreRole role) { + public DataStore findStore(long objId, DataObjectType type, DataStoreRole role) { DataStore store = null; if (role == DataStoreRole.Image) { SearchCriteriaService sc = SearchCriteria2.create(ObjectInDataStoreVO.class); sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role); - sc.addAnd(sc.getEntity().getObjectUuid(), Op.EQ, objUuid); + sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId); sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type); ObjectInDataStoreVO vo = sc.find(); if (vo != null) { - store = this.storeMgr.getDataStore(vo.getDataStoreUuid(), vo.getDataStoreRole()); + store = this.storeMgr.getDataStore(vo.getDataStoreId(), vo.getDataStoreRole()); } } return store; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index 0fbcbb1f956..7b44de0ce91 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -46,15 +46,15 @@ public class ObjectInDataStoreVO implements StateObject 0) { + TemplateInfo tmpl = store.getTemplate(template.getId()); + if (tmpl != null) { + return tmpl; + } + try { + Thread.sleep(sleepTime * 1000); + } catch (InterruptedException e) { + s_logger.debug("waiting for template download been interrupted: " + e.toString()); + } + tries--; + } + return null; + } @DB protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture future) { @@ -293,8 +316,21 @@ public class VolumeServiceImpl implements VolumeService { caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)) .setContext(context); - templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); - + try { + templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); + } catch (Exception e) { + try { + templateOnPrimaryStoreObj = waitForTemplateDownloaded(dataStore, template); + } finally { + if (templateOnPrimaryStoreObj == null) { + VolumeApiResult result = new VolumeApiResult(volume); + result.setResult(e.toString()); + caller.complete(result); + return; + } + } + } + try { motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); } catch (Exception e) { From cd2d066fdad50b01bacc7d2e9a20b14978255c95 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 11 Apr 2013 11:34:33 -0700 Subject: [PATCH 019/303] Add new api to gen_toc.py to avoid api-doc build error. --- client/tomcatconf/commands.properties.in | 2 -- server/src/com/cloud/server/ManagementServerImpl.java | 7 +++++-- tools/apidoc/gen_toc.py | 3 +++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index d2828493f34..002da875cae 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -245,8 +245,6 @@ listS3s=1 addImageStore=1 listImageStores=1 deleteImageStore=1 -enableImageStore=1 - #### host commands addHost=3 diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index af77ba5645f..ee0fbdb1c52 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -466,11 +466,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe public ManagementServerImpl() { setRunLevel(ComponentLifecycle.RUN_LEVEL_APPLICATION_MAINLOOP); } - + public List getUserAuthenticators() { return _userAuthenticators; } - + public void setUserAuthenticators(List authenticators) { _userAuthenticators = authenticators; } @@ -2301,6 +2301,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AssignToGlobalLoadBalancerRuleCmd.class); cmdList.add(RemoveFromGlobalLoadBalancerRuleCmd.class); cmdList.add(ListStorageProvidersCmd.class); + cmdList.add(AddImageStoreCmd.class); + cmdList.add(ListImageStoresCmd.class); + cmdList.add(DeleteImageStoreCmd.class); return cmdList; } diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index e41e883066a..07ef0f58f96 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -138,6 +138,9 @@ known_categories = { 'addIpToNic': 'Nic', 'removeIpFromNic': 'Nic', 'listNics':'Nic', + 'addImageStore': 'Image Store', + 'listImageStores': 'Image Store', + 'deleteImageStore': 'Image Store', } From 582a1f0539869290d65d4a05b7ccf2897205f859 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 11 Apr 2013 11:54:30 -0700 Subject: [PATCH 020/303] Fix ImageStoreDaoImpl to return only image stores, not image cache stores. --- .../storage/image/db/ImageStoreDaoImpl.java | 10 ++++++++-- .../com/cloud/storage/download/DownloadListener.java | 11 +++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 5bcf2f32691..ee0782217b8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -24,6 +24,7 @@ import java.util.Map; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; @@ -50,10 +51,12 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem nameSearch = createSearchBuilder(); nameSearch.and("name", nameSearch.entity().getName(), SearchCriteria.Op.EQ); + nameSearch.and("role", nameSearch.entity().getRole(), SearchCriteria.Op.EQ); nameSearch.done(); providerSearch = createSearchBuilder(); providerSearch.and("providerName", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ); + providerSearch.and("role", providerSearch.entity().getProviderName(), SearchCriteria.Op.EQ); providerSearch.done(); return true; @@ -76,8 +79,11 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem @Override public List findByScope(ZoneScope scope) { SearchCriteria sc = createSearchCriteria(); - sc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION); - sc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.Image); + SearchCriteria scc = createSearchCriteria(); + scc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION); + scc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + sc.addAnd("scope", SearchCriteria.Op.SC, scc); return listBy(sc); } diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 2741af1d898..8e979abdfd9 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -474,17 +474,20 @@ public class DownloadListener implements Listener { @Override public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { + downloadMonitor.handleSysTemplateDownload(agent); - } else if ( cmd instanceof StartupStorageCommand) { + } + /* This can be removed since + else if ( cmd instanceof StartupStorageCommand) { StartupStorageCommand storage = (StartupStorageCommand)cmd; if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE || storage.getResourceType() == Storage.StorageResourceType.LOCAL_SECONDARY_STORAGE ) { downloadMonitor.addSystemVMTemplatesToHost(agent, storage.getTemplateInfo()); - // DO we need to do sync here since we have been doing sync in StartupSecondaryStorageCommand? - // downloadMonitor.handleTemplateSync(agent); + downloadMonitor.handleTemplateSync(agent); downloadMonitor.handleVolumeSync(agent); } - } else if ( cmd instanceof StartupSecondaryStorageCommand ) { + }*/ + else if ( cmd instanceof StartupSecondaryStorageCommand ) { downloadMonitor.handleSync(agent.getDataCenterId()); } } From bb64672715e50f232373f24b2562c434a6e2ab64 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 11 Apr 2013 18:09:42 -0700 Subject: [PATCH 021/303] Refactor DownloadMonitorImpl code, move some functionalities to TemplateServiceImpl and VolumeServiceImpl. --- .../agent/api/ModifyStoragePoolAnswer.java | 10 +- .../agent/api/StartupStorageCommand.java | 12 +- .../agent/api/storage/ListTemplateAnswer.java | 10 +- .../agent/api/storage/ListVolumeAnswer.java | 10 +- .../{TemplateInfo.java => TemplateProp.java} | 8 +- ...teService.java => TemplateApiService.java} | 2 +- .../org/apache/cloudstack/api/BaseCmd.java | 4 +- client/tomcatconf/applicationContext.xml.in | 2 +- .../hyperv/resource/HypervResource.java | 4 +- .../CifsSecondaryStorageResource.java | 4 +- .../LocalSecondaryStorageResource.java | 4 +- .../resource/NfsSecondaryStorageResource.java | 14 +- .../storage/template/DownloadManager.java | 4 +- .../storage/template/DownloadManagerImpl.java | 12 +- .../storage/template/TemplateLocation.java | 4 +- ...ImageService.java => TemplateService.java} | 10 +- .../subsystem/api/storage/VolumeService.java | 18 +- .../datastore/db/SnapshotDataStoreDao.java | 2 - .../datastore/db/TemplateDataStoreDao.java | 6 +- .../datastore/db/TemplateDataStoreVO.java | 6 + .../datastore/db/VolumeDataStoreDao.java | 7 +- .../datastore/db/VolumeDataStoreVO.java | 4 +- .../storage/image/ImageServiceImpl.java | 147 ----- .../storage/image/TemplateServiceImpl.java | 481 +++++++++++++++++ .../storage/test/volumeServiceTest.java | 4 +- .../image/db/SnapshotDataStoreDaoImpl.java | 17 +- .../image/db/TemplateDataStoreDaoImpl.java | 36 +- .../image/db/VolumeDataStoreDaoImpl.java | 46 +- .../storage/volume/VolumeObject.java | 4 + .../storage/volume/VolumeServiceImpl.java | 299 +++++++--- .../resource/LibvirtComputingResource.java | 4 +- .../cloud/ovm/hypervisor/OvmResourceBase.java | 4 +- .../agent/manager/MockStorageManagerImpl.java | 14 +- .../cloud/resource/AgentRoutingResource.java | 4 +- .../vmware/resource/VmwareResource.java | 4 +- .../xen/resource/CitrixResourceBase.java | 4 +- plugins/storage/image/default/pom.xml | 10 + .../CloudStackImageStoreDriverImpl.java | 8 +- plugins/storage/image/s3/pom.xml | 10 + .../driver/S3ImageStoreDriverImpl.java | 8 +- plugins/storage/image/sample/pom.xml | 10 + plugins/storage/image/swift/pom.xml | 10 + .../driver/SwiftImageStoreDriverImpl.java | 8 +- .../com/cloud/storage/StorageManagerImpl.java | 6 +- .../storage/download/DownloadListener.java | 327 ++++++----- .../storage/download/DownloadMonitor.java | 17 +- .../storage/download/DownloadMonitorImpl.java | 510 ++---------------- .../DummySecondaryStorageResource.java | 10 +- .../template/HypervisorTemplateAdapter.java | 4 +- .../com/cloud/template/TemplateManager.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 8 +- 51 files changed, 1174 insertions(+), 999 deletions(-) rename api/src/com/cloud/storage/template/{TemplateInfo.java => TemplateProp.java} (91%) rename api/src/com/cloud/template/{TemplateService.java => TemplateApiService.java} (98%) rename engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/{ImageService.java => TemplateService.java} (86%) delete mode 100644 engine/storage/image/src/org/apache/cloudstack/storage/image/ImageServiceImpl.java create mode 100644 engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java diff --git a/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java b/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java index df77985248f..ed7043a8ec4 100644 --- a/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java +++ b/api/src/com/cloud/agent/api/ModifyStoragePoolAnswer.java @@ -18,16 +18,16 @@ package com.cloud.agent.api; import java.util.Map; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; public class ModifyStoragePoolAnswer extends Answer { StoragePoolInfo poolInfo; - Map templateInfo; + Map templateInfo; protected ModifyStoragePoolAnswer() { } - public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map tInfo) { + public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, long capacityBytes, long availableBytes, Map tInfo) { super(cmd); this.result = true; this.poolInfo = new StoragePoolInfo(null, @@ -46,11 +46,11 @@ public class ModifyStoragePoolAnswer extends Answer { } - public Map getTemplateInfo() { + public Map getTemplateInfo() { return templateInfo; } - public void setTemplateInfo(Map templateInfo) { + public void setTemplateInfo(Map templateInfo) { this.templateInfo = templateInfo; } diff --git a/api/src/com/cloud/agent/api/StartupStorageCommand.java b/api/src/com/cloud/agent/api/StartupStorageCommand.java index 3c3b058ce39..52ed3ffdff3 100755 --- a/api/src/com/cloud/agent/api/StartupStorageCommand.java +++ b/api/src/com/cloud/agent/api/StartupStorageCommand.java @@ -22,13 +22,13 @@ import java.util.Map; import com.cloud.host.Host; import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; public class StartupStorageCommand extends StartupCommand { String parent; - Map templateInfo; + Map templateInfo; long totalSize; StoragePoolInfo poolInfo; Storage.StorageResourceType resourceType; @@ -40,7 +40,7 @@ public class StartupStorageCommand extends StartupCommand { super(Host.Type.Storage); } - public StartupStorageCommand(String parent, StoragePoolType fsType, long totalSize, Map info) { + public StartupStorageCommand(String parent, StoragePoolType fsType, long totalSize, Map info) { super(Host.Type.Storage); this.parent = parent; this.totalSize = totalSize; @@ -50,7 +50,7 @@ public class StartupStorageCommand extends StartupCommand { } - public StartupStorageCommand(String parent, StoragePoolType fsType, Map templateInfo, StoragePoolInfo poolInfo) { + public StartupStorageCommand(String parent, StoragePoolType fsType, Map templateInfo, StoragePoolInfo poolInfo) { super(Host.Type.Storage); this.parent = parent; this.templateInfo = templateInfo; @@ -79,11 +79,11 @@ public class StartupStorageCommand extends StartupCommand { return totalSize; } - public Map getTemplateInfo() { + public Map getTemplateInfo() { return templateInfo; } - public void setTemplateInfo(Map templateInfo) { + public void setTemplateInfo(Map templateInfo) { this.templateInfo = templateInfo; } diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java b/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java index a4e2e255001..4155a632384 100644 --- a/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java +++ b/api/src/com/cloud/agent/api/storage/ListTemplateAnswer.java @@ -19,27 +19,27 @@ package com.cloud.agent.api.storage; import java.util.Map; import com.cloud.agent.api.Answer; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; public class ListTemplateAnswer extends Answer { private String secUrl; - private Map templateInfos; + private Map templateInfos; public ListTemplateAnswer() { } - public ListTemplateAnswer(String secUrl, Map templateInfos) { + public ListTemplateAnswer(String secUrl, Map templateInfos) { super(null, true, "success"); this.setSecUrl(secUrl); this.templateInfos = templateInfos; } - public Map getTemplateInfo() { + public Map getTemplateInfo() { return templateInfos; } - public void setTemplateInfo(Map templateInfos) { + public void setTemplateInfo(Map templateInfos) { this.templateInfos = templateInfos; } diff --git a/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java b/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java index 6bbb2e82c33..31ea09b7d7c 100755 --- a/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java +++ b/api/src/com/cloud/agent/api/storage/ListVolumeAnswer.java @@ -19,27 +19,27 @@ package com.cloud.agent.api.storage; import java.util.Map; import com.cloud.agent.api.Answer; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; public class ListVolumeAnswer extends Answer { private String secUrl; - private Map templateInfos; + private Map templateInfos; public ListVolumeAnswer() { } - public ListVolumeAnswer(String secUrl, Map templateInfos) { + public ListVolumeAnswer(String secUrl, Map templateInfos) { super(null, true, "success"); this.setSecUrl(secUrl); this.templateInfos = templateInfos; } - public Map getTemplateInfo() { + public Map getTemplateInfo() { return templateInfos; } - public void setTemplateInfo(Map templateInfos) { + public void setTemplateInfo(Map templateInfos) { this.templateInfos = templateInfos; } diff --git a/api/src/com/cloud/storage/template/TemplateInfo.java b/api/src/com/cloud/storage/template/TemplateProp.java similarity index 91% rename from api/src/com/cloud/storage/template/TemplateInfo.java rename to api/src/com/cloud/storage/template/TemplateProp.java index 6559d73b18d..0a2efc12e67 100644 --- a/api/src/com/cloud/storage/template/TemplateInfo.java +++ b/api/src/com/cloud/storage/template/TemplateProp.java @@ -16,7 +16,7 @@ // under the License. package com.cloud.storage.template; -public class TemplateInfo { +public class TemplateProp { String templateName; String installPath; long size; @@ -25,11 +25,11 @@ public class TemplateInfo { boolean isPublic; boolean isCorrupted; - protected TemplateInfo() { + protected TemplateProp() { } - public TemplateInfo(String templateName, String installPath, long size, long physicalSize, boolean isPublic, boolean isCorrupted) { + public TemplateProp(String templateName, String installPath, long size, long physicalSize, boolean isPublic, boolean isCorrupted) { this.templateName = templateName; this.installPath = installPath; this.size = size; @@ -38,7 +38,7 @@ public class TemplateInfo { this.isCorrupted = isCorrupted; } - public TemplateInfo(String templateName, String installPath, boolean isPublic, boolean isCorrupted) { + public TemplateProp(String templateName, String installPath, boolean isPublic, boolean isCorrupted) { this(templateName, installPath, 0, 0, isPublic, isCorrupted); } diff --git a/api/src/com/cloud/template/TemplateService.java b/api/src/com/cloud/template/TemplateApiService.java similarity index 98% rename from api/src/com/cloud/template/TemplateService.java rename to api/src/com/cloud/template/TemplateApiService.java index 7e831fb0055..50373fef651 100755 --- a/api/src/com/cloud/template/TemplateService.java +++ b/api/src/com/cloud/template/TemplateApiService.java @@ -36,7 +36,7 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.user.Account; import com.cloud.utils.exception.CloudRuntimeException; -public interface TemplateService { +public interface TemplateApiService { VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException; diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 78a2af36aa2..b845053e470 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -65,7 +65,7 @@ import com.cloud.storage.DataStoreProviderApiService; import com.cloud.storage.StorageService; import com.cloud.storage.VolumeApiService; import com.cloud.storage.snapshot.SnapshotService; -import com.cloud.template.TemplateService; +import com.cloud.template.TemplateApiService; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.DomainService; @@ -106,7 +106,7 @@ public abstract class BaseCmd { @Inject public VolumeApiService _volumeService; @Inject public ResourceService _resourceService; @Inject public NetworkService _networkService; - @Inject public TemplateService _templateService; + @Inject public TemplateApiService _templateService; @Inject public SecurityGroupService _securityGroupService; @Inject public SnapshotService _snapshotService; @Inject public ConsoleProxyService _consoleProxyService; diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 206afd3c8f3..7ad3bb50f9c 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -744,7 +744,7 @@ - + diff --git a/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java index 0f9b3dd9c6b..725f0cc1ae2 100755 --- a/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java +++ b/core/src/com/cloud/hypervisor/hyperv/resource/HypervResource.java @@ -105,7 +105,7 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.ServerResourceBase; import com.cloud.serializer.GsonHelper; import com.cloud.storage.Volume; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; @@ -765,7 +765,7 @@ public class HypervResource extends ServerResourceBase implements ServerResource try { StorageFilerTO pool = cmd.getPool(); s_logger.info("Primary storage pool details: " + pool.getHost() + " " + pool.getPath()); - Map tInfo = new HashMap(); + Map tInfo = new HashMap(); // FIXME: get the actual storage capacity and storage stats of CSV volume // by running powershell cmdlet. This hardcoding just for prototype. ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, diff --git a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java index 285005a1c3a..435e0f713dc 100755 --- a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java @@ -60,7 +60,7 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.UploadManager; import com.cloud.storage.template.UploadManagerImpl; import com.cloud.utils.NumbersUtil; @@ -650,7 +650,7 @@ public class CifsSecondaryStorageResource extends ServerResourceBase implements return null; }*/ - final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap()); + final StartupStorageCommand cmd = new StartupStorageCommand(_parent, StoragePoolType.NetworkFilesystem, getTotalSize(), new HashMap()); cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE); cmd.setIqn(null); diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java index c638c5d874e..89d0fe1836e 100644 --- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java @@ -48,7 +48,7 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.utils.component.ComponentContext; public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource { @@ -109,7 +109,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements private Answer execute(ListTemplateCommand cmd) { String root = getRootDir(); - Map templateInfos = _dlMgr.gatherTemplateInfo(root); + Map templateInfos = _dlMgr.gatherTemplateInfo(root); return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index e65cbe1312e..a8788c66b64 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -100,7 +100,7 @@ import com.cloud.storage.StorageLayer; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.UploadManager; import com.cloud.storage.template.UploadManagerImpl; @@ -1073,12 +1073,12 @@ SecondaryStorageResource { } } - Map swiftListTemplate(SwiftTO swift) { + Map swiftListTemplate(SwiftTO swift) { String[] containers = swiftList(swift, "", ""); if (containers == null) { return null; } - Map tmpltInfos = new HashMap(); + Map tmpltInfos = new HashMap(); for( String container : containers) { if ( container.startsWith("T-")) { String ldir = _tmpltDir + "/" + UUID.randomUUID().toString(); @@ -1095,7 +1095,7 @@ SecondaryStorageResource { s_logger.warn("Unable to load template location " + ldir + " due to " + e.toString(), e); continue; } - TemplateInfo tInfo = loc.getTemplateInfo(); + TemplateProp tInfo = loc.getTemplateInfo(); tInfo.setInstallPath(container); tmpltInfos.put(tInfo.getTemplateName(), tInfo); loc.purge(); @@ -1111,11 +1111,11 @@ SecondaryStorageResource { return new Answer(cmd, true, null); } if (cmd.getSwift() != null) { - Map templateInfos = swiftListTemplate(cmd.getSwift()); + Map templateInfos = swiftListTemplate(cmd.getSwift()); return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos); } else { String root = getRootDir(cmd.getSecUrl()); - Map templateInfos = _dlMgr.gatherTemplateInfo(root); + Map templateInfos = _dlMgr.gatherTemplateInfo(root); return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); } } @@ -1126,7 +1126,7 @@ SecondaryStorageResource { } String root = getRootDir(cmd.getSecUrl()); - Map templateInfos = _dlMgr.gatherVolumeInfo(root); + Map templateInfos = _dlMgr.gatherVolumeInfo(root); return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); } diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java index f4f8a0f17fa..82f4153f6e2 100644 --- a/core/src/com/cloud/storage/template/DownloadManager.java +++ b/core/src/com/cloud/storage/template/DownloadManager.java @@ -91,13 +91,13 @@ public interface DownloadManager extends Manager { /** * @return list of template info for installed templates */ - public Map gatherTemplateInfo(String templateDir); + public Map gatherTemplateInfo(String templateDir); /** /** * @return list of volume info for installed volumes */ - public Map gatherVolumeInfo(String volumeDir); + public Map gatherVolumeInfo(String volumeDir); } \ No newline at end of file diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 22e78a081c1..db264c17bb1 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -717,8 +717,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } @Override - public Map gatherTemplateInfo(String rootDir) { - Map result = new HashMap(); + public Map gatherTemplateInfo(String rootDir) { + Map result = new HashMap(); String templateDir = rootDir + File.separator + _templateDir; if (! _storage.exists(templateDir)) { @@ -741,7 +741,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager continue; } - TemplateInfo tInfo = loc.getTemplateInfo(); + TemplateProp tInfo = loc.getTemplateInfo(); if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) { try { @@ -774,8 +774,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } @Override - public Map gatherVolumeInfo(String rootDir) { - Map result = new HashMap(); + public Map gatherVolumeInfo(String rootDir) { + Map result = new HashMap(); String volumeDir = rootDir + File.separator + _volumeDir; if (! _storage.exists(volumeDir)) { @@ -798,7 +798,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager continue; } - TemplateInfo vInfo = loc.getTemplateInfo(); + TemplateProp vInfo = loc.getTemplateInfo(); if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) { try { diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java index 58d023a4907..515b1f2343f 100644 --- a/core/src/com/cloud/storage/template/TemplateLocation.java +++ b/core/src/com/cloud/storage/template/TemplateLocation.java @@ -156,8 +156,8 @@ public class TemplateLocation { return true; } - public TemplateInfo getTemplateInfo() { - TemplateInfo tmplInfo = new TemplateInfo(); + public TemplateProp getTemplateInfo() { + TemplateProp tmplInfo = new TemplateProp(); tmplInfo.id = Long.parseLong(_props.getProperty("id")); tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename"); if (_resourceType == ResourceType.VOLUME){ diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java similarity index 86% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index 119f3b1d32f..6bb58e0d4d6 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -20,10 +20,16 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.framework.async.AsyncCallFuture; -public interface ImageService { + + +import com.cloud.hypervisor.Hypervisor.HypervisorType; + +public interface TemplateService { AsyncCallFuture createTemplateAsync(TemplateInfo template, DataStore store); AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); AsyncCallFuture deleteTemplateAsync(TemplateInfo template); - + + void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId); + void handleTemplateSync(DataStore store); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java index 102c47174b1..7175524c87e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java @@ -25,13 +25,13 @@ import com.cloud.exception.ConcurrentOperationException; public interface VolumeService { - + public class VolumeApiResult extends CommandResult { private final VolumeInfo volume; public VolumeApiResult(VolumeInfo volume) { this.volume = volume; } - + public VolumeInfo getVolume() { return this.volume; } @@ -39,16 +39,16 @@ public interface VolumeService { /** * Creates the volume based on the given criteria - * + * * @param cmd - * + * * @return the volume object */ AsyncCallFuture createVolumeAsync(VolumeInfo volume, DataStore store); /** * Delete volume - * + * * @param volumeId * @return * @throws ConcurrentOperationException @@ -56,12 +56,12 @@ public interface VolumeService { AsyncCallFuture expungeVolumeAsync(VolumeInfo volume); /** - * + * */ boolean cloneVolume(long volumeId, long baseVolId); /** - * + * */ AsyncCallFuture createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot); @@ -74,7 +74,9 @@ public interface VolumeService { boolean destroyVolume(long volumeId) throws ConcurrentOperationException; AsyncCallFuture registerVolume(VolumeInfo volume, DataStore store); - + AsyncCallFuture resize(VolumeInfo volume); + void handleVolumeSync(DataStore store); + } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index 91ffdaa01c2..271ff41f08e 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -30,7 +30,5 @@ public interface SnapshotDataStoreDao extends GenericDao listByStoreId(long id); - public List listLiveByStoreId(long id); - public void deletePrimaryRecordsForStore(long id); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index 29c7859960b..f1fcdcc65d9 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -23,18 +23,20 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; public interface TemplateDataStoreDao extends GenericDao, StateDao { - public List listByStoreId(long id); - public List listLiveByStoreId(long id); + public List listByStoreId(long id); public void deletePrimaryRecordsForStore(long id); List listByTemplateStoreStatus(long templateId, long storeId, State... states); + List listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status); + TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index 312fd119adc..d7c8443d71c 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -291,6 +291,12 @@ public class TemplateDataStoreVO implements StateObject, public List listByStoreId(long id); - public List listLiveByStoreId(long id); - public void deletePrimaryRecordsForStore(long id); + + public VolumeDataStoreVO findByVolumeId(long volumeId); + + public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index 185b12b52f1..a7134ea374c 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -203,14 +203,14 @@ public class VolumeDataStoreVO implements StateObject extends AsyncRpcConext { - final TemplateInfo srcTemplate; - final DataStore store; - final AsyncCallFuture future; - final DataObject templateOnStore; - - public CreateTemplateContext(AsyncCompletionCallback callback, TemplateInfo srcTemplate, - AsyncCallFuture future, - DataStore store, - DataObject templateOnStore - ) { - super(callback); - this.srcTemplate = srcTemplate; - this.future = future; - this.store = store; - this.templateOnStore = templateOnStore; - } - } - - @Override - public AsyncCallFuture createTemplateAsync( - TemplateInfo template, DataStore store) { - TemplateObject to = (TemplateObject) template; - AsyncCallFuture future = new AsyncCallFuture(); - // persist template_store_ref entry - DataObject templateOnStore = store.create(template); - // update template_store_ref state - templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); - - CreateTemplateContext context = new CreateTemplateContext(null, - template, - future, - store, - templateOnStore - ); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); - store.getDriver().createAsync(templateOnStore, caller); - return future; - } - - protected Void createTemplateCallback(AsyncCallbackDispatcher callback, - CreateTemplateContext context) { - TemplateObject template = (TemplateObject)context.srcTemplate; - AsyncCallFuture future = context.future; - CommandResult result = new CommandResult(); - DataObject templateOnStore = context.templateOnStore; - CreateCmdResult callbackResult = callback.getResult(); - if (callbackResult.isFailed()) { - try { - templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); - template.stateTransit(TemplateEvent.OperationFailed); - } catch (NoTransitionException e) { - s_logger.debug("Failed to update template state", e); - } - result.setResult(callbackResult.getResult()); - future.complete(result); - return null; - } - - try { - templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); - template.stateTransit(TemplateEvent.OperationSucceeded); - } catch (NoTransitionException e) { - s_logger.debug("Failed to transit state", e); - result.setResult(e.toString()); - future.complete(result); - return null; - } - - future.complete(result); - return null; - } - - @Override - public AsyncCallFuture deleteTemplateAsync( - TemplateInfo template) { - // TODO Auto-generated method stub - return null; - } - - @Override - public AsyncCallFuture createTemplateFromSnapshotAsync( - SnapshotInfo snapshot, TemplateInfo template, DataStore store) { - // TODO Auto-generated method stub - return null; - } - - @Override - public AsyncCallFuture createTemplateFromVolumeAsync( - VolumeInfo volume, TemplateInfo template, DataStore store) { - // TODO Auto-generated method stub - return null; - } -} diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java new file mode 100644 index 00000000000..3dcb86b0939 --- /dev/null +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -0,0 +1,481 @@ +/* + * 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 java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import com.cloud.storage.template.TemplateProp; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.datastore.DataObjectManager; +import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DeleteTemplateCommand; +import com.cloud.agent.api.storage.ListTemplateAnswer; +import com.cloud.agent.api.storage.ListTemplateCommand; +import com.cloud.alert.AlertManager; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.exception.AgentUnavailableException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VMTemplateZoneDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.user.AccountManager; +import com.cloud.user.ResourceLimitService; +import com.cloud.utils.UriUtils; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; + +@Component +public class TemplateServiceImpl implements TemplateService { + private static final Logger s_logger = Logger.getLogger(TemplateServiceImpl.class); + @Inject + ObjectInDataStoreManager _objectInDataStoreMgr; + @Inject + DataObjectManager _dataObjectMgr; + @Inject + DataStoreManager _storeMgr; + @Inject + ResourceLimitService _resourceLimitMgr; + @Inject + AccountManager _accountMgr; + @Inject + AlertManager _alertMgr; + @Inject + VMTemplateDao _templateDao; + @Inject + TemplateDataStoreDao _vmTemplateStoreDao; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + DownloadMonitor _dlMonitor; + @Inject + AgentManager _agentMgr; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + DataCenterDao _dcDao = null; + @Inject + VMTemplateZoneDao _vmTemplateZoneDao; + @Inject + ClusterDao _clusterDao; + @Inject + UserVmDao _userVmDao; + @Inject + VolumeDao _volumeDao; + + + class CreateTemplateContext extends AsyncRpcConext { + final TemplateInfo srcTemplate; + final DataStore store; + final AsyncCallFuture future; + final DataObject templateOnStore; + + public CreateTemplateContext(AsyncCompletionCallback callback, TemplateInfo srcTemplate, + AsyncCallFuture future, + DataStore store, + DataObject templateOnStore + ) { + super(callback); + this.srcTemplate = srcTemplate; + this.future = future; + this.store = store; + this.templateOnStore = templateOnStore; + } + } + + @Override + public AsyncCallFuture createTemplateAsync( + TemplateInfo template, DataStore store) { + TemplateObject to = (TemplateObject) template; + AsyncCallFuture future = new AsyncCallFuture(); + // persist template_store_ref entry + DataObject templateOnStore = store.create(template); + // update template_store_ref state + templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); + + CreateTemplateContext context = new CreateTemplateContext(null, + template, + future, + store, + templateOnStore + ); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); + store.getDriver().createAsync(templateOnStore, caller); + return future; + } + + + @Override + public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { + Set toBeDownloaded = new HashSet(); + List ssHosts = this._storeMgr.getImageStoresByScope(new ZoneScope(dcId)); + if (ssHosts == null || ssHosts.isEmpty()){ + return; + } + + /*Download all the templates in zone with the same hypervisortype*/ + for ( DataStore ssHost : ssHosts) { + List rtngTmplts = _templateDao.listAllSystemVMTemplates(); + List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); + + + for (VMTemplateVO rtngTmplt : rtngTmplts) { + if (rtngTmplt.getHypervisorType() == hostHyper) { + toBeDownloaded.add(rtngTmplt); + } + } + + for (VMTemplateVO builtinTmplt : defaultBuiltin) { + if (builtinTmplt.getHypervisorType() == hostHyper) { + toBeDownloaded.add(builtinTmplt); + } + } + + for (VMTemplateVO template: toBeDownloaded) { + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(ssHost.getId(), template.getId()); + if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { + _dlMonitor.downloadTemplateToStorage(template, ssHost, null); + } + } + } + } + + + + + + @Override + public void handleTemplateSync(DataStore store) { + if (store == null) { + s_logger.warn("Huh? image store is null"); + return; + } + long storeId = store.getId(); + Long zoneId = store.getScope().getScopeId(); + + Map templateInfos = listTemplate(store); + if (templateInfos == null) { + return; + } + + Set toBeDownloaded = new HashSet(); + List allTemplates = null; + if (zoneId == null){ + // region wide store + allTemplates = _templateDao.listAll(); + } + else{ + // zone wide store + allTemplates = _templateDao.listAllInZone(zoneId); + } + List rtngTmplts = _templateDao.listAllSystemVMTemplates(); + List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); + + if (rtngTmplts != null) { + for (VMTemplateVO rtngTmplt : rtngTmplts) { + if (!allTemplates.contains(rtngTmplt)) { + allTemplates.add(rtngTmplt); + } + } + } + + if (defaultBuiltin != null) { + for (VMTemplateVO builtinTmplt : defaultBuiltin) { + if (!allTemplates.contains(builtinTmplt)) { + allTemplates.add(builtinTmplt); + } + } + } + + toBeDownloaded.addAll(allTemplates); + + for (VMTemplateVO tmplt : allTemplates) { + String uniqueName = tmplt.getUniqueName(); + TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); + if (templateInfos.containsKey(uniqueName)) { + TemplateProp tmpltInfo = templateInfos.remove(uniqueName); + toBeDownloaded.remove(tmplt); + if (tmpltStore != null) { + s_logger.info("Template Sync found " + uniqueName + " already in the template host table"); + if (tmpltStore.getDownloadState() != Status.DOWNLOADED) { + tmpltStore.setErrorString(""); + } + if (tmpltInfo.isCorrupted()) { + tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR); + String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId(); + tmpltStore.setErrorString(msg); + s_logger.info("msg"); + if (tmplt.getUrl() == null) { + msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId(); + s_logger.warn(msg); + } else { + toBeDownloaded.add(tmplt); + } + + } else { + tmpltStore.setDownloadPercent(100); + tmpltStore.setDownloadState(Status.DOWNLOADED); + tmpltStore.setInstallPath(tmpltInfo.getInstallPath()); + tmpltStore.setSize(tmpltInfo.getSize()); + tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); + tmpltStore.setLastUpdated(new Date()); + + if (tmpltInfo.getSize() > 0) { + long accountId = tmplt.getAccountId(); + try { + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), + com.cloud.configuration.Resource.ResourceType.secondary_storage, + tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl())); + } catch (ResourceAllocationException e) { + s_logger.warn(e.getMessage()); + _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, + null, e.getMessage(), e.getMessage()); + } finally { + _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), + com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); + } + } + } + _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore); + } else { + tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); + tmpltStore.setSize(tmpltInfo.getSize()); + tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); + _vmTemplateStoreDao.persist(tmpltStore); + this.associateTemplateToZone(tmplt.getId(), zoneId); + } + + continue; + } + if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) { + s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly"); + + } else if (tmpltStore == null) { + s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly"); + TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); + _vmTemplateStoreDao.persist(templtStore); + this.associateTemplateToZone(tmplt.getId(), zoneId); + } + + } + + if (toBeDownloaded.size() > 0) { + /* Only download templates whose hypervirsor type is in the zone */ + List availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId); + if (availHypers.isEmpty()) { + /* + * This is for cloudzone, local secondary storage resource + * started before cluster created + */ + availHypers.add(HypervisorType.KVM); + } + /* Baremetal need not to download any template */ + availHypers.remove(HypervisorType.BareMetal); + availHypers.add(HypervisorType.None); // bug 9809: resume ISO + // download. + for (VMTemplateVO tmplt : toBeDownloaded) { + if (tmplt.getUrl() == null) { // If url is null we can't + // initiate the download + continue; + } + // check if there is a record for this template in this store + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); + + // if this is private template, and there is no record for this + // template in this store, skip + if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) { + if (tmpltHost == null) { + continue; + } + } + if (availHypers.contains(tmplt.getHypervisorType())) { + if (tmpltHost != null ) { + continue; + } + s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName()); + //TODO: we should pass a callback here + _dlMonitor.downloadTemplateToStorage(tmplt, store, null); + } + } + } + + for (String uniqueName : templateInfos.keySet()) { + TemplateProp tInfo = templateInfos.get(uniqueName); + List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); + //check if there is any Vm using this ISO. + if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getUri(), tInfo.getInstallPath()); + try { + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); + } catch (AgentUnavailableException e) { + String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database"; + s_logger.error(err); + return; + } + + String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database"; + s_logger.info(description); + } + } + + } + + + // persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case, + // we will associate the template to all the zones. + private void associateTemplateToZone(long templateId, Long zoneId){ + List dcs = new ArrayList(); + if (zoneId != null ){ + dcs.add(zoneId); + } + else{ + List zones = _dcDao.listAll(); + for (DataCenterVO zone : zones){ + dcs.add(zone.getId()); + } + } + for (Long id : dcs) { + VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId); + if (tmpltZoneVO == null) { + tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date()); + _vmTemplateZoneDao.persist(tmpltZoneVO); + } else { + tmpltZoneVO.setLastUpdated(new Date()); + _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); + } + } + } + + + private Map listTemplate(DataStore ssHost) { + ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri()); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost); + Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd); + if (answer != null && answer.getResult()) { + ListTemplateAnswer tanswer = (ListTemplateAnswer)answer; + return tanswer.getTemplateInfo(); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("can not list template for secondary storage host " + ssHost.getId()); + } + } + + return null; + } + + + protected Void createTemplateCallback(AsyncCallbackDispatcher callback, + CreateTemplateContext context) { + TemplateObject template = (TemplateObject)context.srcTemplate; + AsyncCallFuture future = context.future; + CommandResult result = new CommandResult(); + DataObject templateOnStore = context.templateOnStore; + CreateCmdResult callbackResult = callback.getResult(); + if (callbackResult.isFailed()) { + try { + templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); + template.stateTransit(TemplateEvent.OperationFailed); + } catch (NoTransitionException e) { + s_logger.debug("Failed to update template state", e); + } + result.setResult(callbackResult.getResult()); + future.complete(result); + return null; + } + + try { + templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); + template.stateTransit(TemplateEvent.OperationSucceeded); + } catch (NoTransitionException e) { + s_logger.debug("Failed to transit state", e); + result.setResult(e.toString()); + future.complete(result); + return null; + } + + future.complete(result); + return null; + } + + @Override + public AsyncCallFuture deleteTemplateAsync( + TemplateInfo template) { + // TODO Auto-generated method stub + return null; + } + + @Override + public AsyncCallFuture createTemplateFromSnapshotAsync( + SnapshotInfo snapshot, TemplateInfo template, DataStore store) { + // TODO Auto-generated method stub + return null; + } + + @Override + public AsyncCallFuture createTemplateFromVolumeAsync( + VolumeInfo volume, TemplateInfo template, DataStore store) { + // TODO Auto-generated method stub + return null; + } + + + +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 293d7fb11c8..fcb89624dde 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -39,7 +39,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -86,7 +86,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { //@Inject //ImageDataStoreProviderManager imageProviderMgr; @Inject - ImageService imageService; + TemplateService imageService; @Inject VolumeService volumeService; @Inject diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 6a6e04a52b3..c9ade1a7523 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -42,21 +42,16 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; - private SearchBuilder liveStoreSearch; @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); - storeSearch = createSearchBuilder(); + storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); storeSearch.done(); - liveStoreSearch = createSearchBuilder(); - liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - liveStoreSearch.done(); - updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -102,17 +97,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase 0; } + @Override public List listByStoreId(long id) { SearchCriteria sc = storeSearch.create(); sc.setParameters("store_id", id); - return listIncludingRemovedBy(sc); - } - - @Override - public List listLiveByStoreId(long id) { - SearchCriteria sc = liveStoreSearch.create(); - sc.setParameters("store_id", id); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index a429dc961d6..e34a1aba885 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -30,6 +30,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -42,23 +43,20 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; - private SearchBuilder liveStoreSearch; private SearchBuilder storeTemplateStateSearch; + private SearchBuilder storeTemplateDownloadStatusSearch; private SearchBuilder storeTemplateSearch; @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); + storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); storeSearch.done(); - liveStoreSearch = createSearchBuilder(); - liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - liveStoreSearch.done(); - updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -72,6 +70,14 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase 0; } + @Override public List listByStoreId(long id) { SearchCriteria sc = storeSearch.create(); sc.setParameters("store_id", id); - return listIncludingRemovedBy(sc); - } - @Override - public List listLiveByStoreId(long id) { - SearchCriteria sc = liveStoreSearch.create(); - sc.setParameters("store_id", id); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); } @@ -152,6 +153,17 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) { + SearchCriteria sc = storeTemplateStateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("store_id", storeId); + sc.setParameters("downloadState", (Object[])status); + return search(sc, null); + } + @Override public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) { SearchCriteria sc = storeTemplateSearch.create(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index 9a93f980b27..dc6c2354952 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.VolumeHostVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -42,21 +43,30 @@ import com.cloud.utils.db.UpdateBuilder; public class VolumeDataStoreDaoImpl extends GenericDaoBase implements VolumeDataStoreDao { private static final Logger s_logger = Logger.getLogger(VolumeDataStoreDaoImpl.class); private SearchBuilder updateStateSearch; + private SearchBuilder volumeSearch; private SearchBuilder storeSearch; - private SearchBuilder liveStoreSearch; + private SearchBuilder storeVolumeSearch; @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); + storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); storeSearch.done(); - liveStoreSearch = createSearchBuilder(); - liveStoreSearch.and("store_id", liveStoreSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - liveStoreSearch.and("destroyed", liveStoreSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - liveStoreSearch.done(); + volumeSearch = createSearchBuilder(); + volumeSearch.and("volume_id", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + volumeSearch.and("destroyed", volumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + volumeSearch.done(); + + storeVolumeSearch = createSearchBuilder(); + storeVolumeSearch.and("store_id", storeVolumeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + storeVolumeSearch.and("volume_id", storeVolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); + storeVolumeSearch.and("destroyed", storeVolumeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + storeVolumeSearch.done(); updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); @@ -102,16 +112,11 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase 0; } + @Override public List listByStoreId(long id) { SearchCriteria sc = storeSearch.create(); sc.setParameters("store_id", id); - return listIncludingRemovedBy(sc); - } - @Override - public List listLiveByStoreId(long id) { - SearchCriteria sc = liveStoreSearch.create(); - sc.setParameters("store_id", id); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); } @@ -125,4 +130,23 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase sc = volumeSearch.create(); + sc.setParameters("volume_id", volumeId); + sc.setParameters("destroyed", false); + return findOneBy(sc); + } + @Override + public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId) { + SearchCriteria sc = storeVolumeSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("volume_id", volumeId); + sc.setParameters("destroyed", false); + return findOneBy(sc); + } + + } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index cde576b79f1..766d219261d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -318,6 +318,10 @@ public class VolumeObject implements VolumeInfo { return this.payload; } + public VolumeVO getVolume(){ + return this.volumeVO; + } + @Override public HypervisorType getHypervisorType() { return this.volumeDao.getHypervisorType(this.volumeVO.getId()); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 2b43adec71a..2da16c1178d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -18,6 +18,11 @@ */ package org.apache.cloudstack.storage.volume; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + import javax.inject.Inject; import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; @@ -41,19 +46,37 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.ListVolumeAnswer; +import com.cloud.agent.api.storage.ListVolumeCommand; +import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.host.HostVO; import com.cloud.storage.StoragePool; import com.cloud.storage.Volume; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.storage.template.TemplateProp; +import com.cloud.user.AccountManager; +import com.cloud.user.ResourceLimitService; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.UriUtils; import com.cloud.utils.db.DB; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; @@ -77,13 +100,29 @@ public class VolumeServiceImpl implements VolumeService { @Inject VolumeDataFactory volFactory; @Inject SnapshotManager snapshotMgr; + @Inject + ResourceLimitService _resourceLimitMgr; + @Inject + DownloadMonitor _dlMonitor; + @Inject + AccountManager _accountMgr; + @Inject + AlertManager _alertMgr; @Inject VMInstanceDao vmDao; @Inject ConfigurationDao configDao; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + AgentManager _agentMgr; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + VolumeDao _volumeDao; public VolumeServiceImpl() { } - + private class CreateVolumeContext extends AsyncRpcConext { private DataObject volume; @@ -96,17 +135,17 @@ public class VolumeServiceImpl implements VolumeService { this.volume = volume; this.future = future; } - + public DataObject getVolume() { return this.volume; } - + public AsyncCallFuture getFuture() { return this.future; } - + } - + @Override public AsyncCallFuture createVolumeAsync(VolumeInfo volume, DataStore dataStore) { AsyncCallFuture future = new AsyncCallFuture(); @@ -117,11 +156,11 @@ public class VolumeServiceImpl implements VolumeService { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeCallback(null, null)) .setContext(context); - + dataStore.getDriver().createAsync(volumeOnStore, caller); return future; } - + protected Void createVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); DataObject vo = context.getVolume(); @@ -139,7 +178,7 @@ public class VolumeServiceImpl implements VolumeService { context.getFuture().complete(volResult); return null; } - + private class DeleteVolumeContext extends AsyncRpcConext { private final VolumeObject volume; private AsyncCallFuture future; @@ -151,11 +190,11 @@ public class VolumeServiceImpl implements VolumeService { this.volume = volume; this.future = future; } - + public VolumeObject getVolume() { return this.volume; } - + public AsyncCallFuture getFuture() { return this.future; } @@ -171,7 +210,7 @@ public class VolumeServiceImpl implements VolumeService { future.complete(result); return future; } - + String vmName = null; VolumeVO vol = this.volDao.findById(volume.getId()); if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) { @@ -194,19 +233,19 @@ public class VolumeServiceImpl implements VolumeService { return future; } VolumeObject vo = (VolumeObject)volume; - + volume.processEvent(Event.ExpungeRequested); - - + + DeleteVolumeContext context = new DeleteVolumeContext(null, vo, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)) .setContext(context); - + volume.getDataStore().getDriver().deleteAsync(volume, caller); return future; } - + public Void deleteVolumeCallback(AsyncCallbackDispatcher callback, DeleteVolumeContext context) { CommandResult result = callback.getResult(); VolumeObject vo = context.getVolume(); @@ -249,7 +288,7 @@ public class VolumeServiceImpl implements VolumeService { private final TemplateInfo srcTemplate; private final AsyncCallFuture future; final DataObject destObj; - public CreateBaseImageContext(AsyncCompletionCallback callback, VolumeInfo volume, PrimaryDataStore datastore, + public CreateBaseImageContext(AsyncCompletionCallback callback, VolumeInfo volume, PrimaryDataStore datastore, TemplateInfo srcTemplate, AsyncCallFuture future, DataObject destObj) { super(callback); @@ -259,11 +298,11 @@ public class VolumeServiceImpl implements VolumeService { this.srcTemplate = srcTemplate; this.destObj = destObj; } - + public VolumeInfo getVolume() { return this.volume; } - + public PrimaryDataStore getDataStore() { return this.dataStore; } @@ -271,13 +310,13 @@ public class VolumeServiceImpl implements VolumeService { public TemplateInfo getSrcTemplate() { return this.srcTemplate; } - + public AsyncCallFuture getFuture() { return this.future; } - + } - + static class CreateBaseImageResult extends CommandResult { final TemplateInfo template; public CreateBaseImageResult(TemplateInfo template) { @@ -285,7 +324,7 @@ public class VolumeServiceImpl implements VolumeService { this.template = template; } } - + private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) { int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); int sleepTime = 120; @@ -306,16 +345,16 @@ public class VolumeServiceImpl implements VolumeService { } @DB protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture future) { - + DataObject templateOnPrimaryStoreObj = dataStore.create(template); - CreateBaseImageContext context = new CreateBaseImageContext(null, volume, + CreateBaseImageContext context = new CreateBaseImageContext(null, volume, dataStore, template, future, templateOnPrimaryStoreObj); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)) .setContext(context); - + try { templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); } catch (Exception e) { @@ -330,7 +369,7 @@ public class VolumeServiceImpl implements VolumeService { } } } - + try { motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); } catch (Exception e) { @@ -342,12 +381,12 @@ public class VolumeServiceImpl implements VolumeService { } return; } - + @DB protected Void copyBaseImageCallback(AsyncCallbackDispatcher callback, CreateBaseImageContext context) { CopyCommandResult result = callback.getResult(); VolumeApiResult res = new VolumeApiResult(context.getVolume()); - + AsyncCallFuture future = context.getFuture(); DataObject templateOnPrimaryStoreObj = context.destObj; if (!result.isSuccess()) { @@ -356,18 +395,18 @@ public class VolumeServiceImpl implements VolumeService { future.complete(res); return null; } - + templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed); createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future); return null; } - + private class CreateVolumeFromBaseImageContext extends AsyncRpcConext { private final VolumeObject vo; private final AsyncCallFuture future; private final DataStore primaryStore; private final DataObject templateOnStore; - public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject vo, + public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject vo, DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture future) { @@ -377,13 +416,13 @@ public class VolumeServiceImpl implements VolumeService { this.primaryStore = primaryStore; this.templateOnStore = templateOnStore; } - + public AsyncCallFuture getFuture() { return this.future; } } - + @DB protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture future) { VolumeObject vo = (VolumeObject)volume; @@ -398,23 +437,23 @@ public class VolumeServiceImpl implements VolumeService { motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller); return; } - + @DB public Void copyBaseImageCallBack(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { VolumeObject vo = context.vo; CopyCommandResult result = callback.getResult(); VolumeApiResult volResult = new VolumeApiResult(vo); - + if (result.isSuccess()) { if (result.getPath() != null) { vo.setPath(result.getPath()); } - vo.processEvent(Event.OperationSuccessed); + vo.processEvent(Event.OperationSuccessed); } else { vo.processEvent(Event.OperationFailed); volResult.setResult(result.getResult()); } - + AsyncCallFuture future = context.getFuture(); future.complete(volResult); return null; @@ -427,12 +466,12 @@ public class VolumeServiceImpl implements VolumeService { TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId()); AsyncCallFuture future = new AsyncCallFuture(); VolumeApiResult result = new VolumeApiResult(volume); - + if (templateOnPrimaryStore == null) { createBaseImageAsync(volume, pd, template, future); return future; } - + createVolumeFromBaseImageAsync(volume, templateOnPrimaryStore, pd, future); return future; } @@ -441,13 +480,13 @@ public class VolumeServiceImpl implements VolumeService { @DB public boolean destroyVolume(long volumeId) throws ConcurrentOperationException { - + VolumeInfo vol = this.volFactory.getVolume(volumeId); vol.processEvent(Event.DestroyRequested); this.snapshotMgr.deletePoliciesForVolume(volumeId); vol.processEvent(Event.OperationSuccessed); - + return true; } @@ -455,11 +494,11 @@ public class VolumeServiceImpl implements VolumeService { public AsyncCallFuture createVolumeFromSnapshot( VolumeInfo volume, DataStore store, SnapshotInfo snapshot) { AsyncCallFuture future = new AsyncCallFuture(); - + try { DataObject volumeOnStore = store.create(volume); volume.processEvent(Event.CreateOnlyRequested); - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, (VolumeObject)volume, store, volumeOnStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)) @@ -471,11 +510,11 @@ public class VolumeServiceImpl implements VolumeService { result.setResult(e.toString()); future.complete(result); } - + return future; } - - protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, + + protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); VolumeInfo volume = context.vo; @@ -487,19 +526,19 @@ public class VolumeServiceImpl implements VolumeService { } else { event = Event.OperationSuccessed; } - + try { volume.processEvent(event); } catch (Exception e) { s_logger.debug("create volume from snapshot failed", e); apiResult.setResult(e.toString()); } - + AsyncCallFuture future = context.future; future.complete(apiResult); return null; } - + protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) { Long lastPoolId = volume.getPoolId(); VolumeVO newVol = new VolumeVO(volume); @@ -511,7 +550,7 @@ public class VolumeServiceImpl implements VolumeService { newVol.setPodId(pool.getPodId()); return this.volDao.persist(newVol); } - + private class CopyVolumeContext extends AsyncRpcConext { final VolumeInfo srcVolume; @@ -529,7 +568,7 @@ public class VolumeServiceImpl implements VolumeService { this.destStore = destStore; this.future = future; } - + } @Override public AsyncCallFuture copyVolume(VolumeInfo srcVolume, @@ -540,7 +579,7 @@ public class VolumeServiceImpl implements VolumeService { if (!this.snapshotMgr.canOperateOnVolume(srcVolume)) { s_logger.debug( "There are snapshots creating on this volume, can not move this volume"); - + res.setResult("There are snapshots creating on this volume, can not move this volume"); future.complete(res); return future; @@ -551,7 +590,7 @@ public class VolumeServiceImpl implements VolumeService { destVolume.processEvent(Event.CreateOnlyRequested); srcVolume.processEvent(Event.CopyingRequested); - CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, + CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, destVolume, destStore); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); @@ -565,7 +604,7 @@ public class VolumeServiceImpl implements VolumeService { } return future; } - + protected Void copyVolumeCallBack(AsyncCallbackDispatcher callback, CopyVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; @@ -593,13 +632,13 @@ public class VolumeServiceImpl implements VolumeService { res.setResult(e.toString()); future.complete(res); } - + return null; } - + @Override public AsyncCallFuture registerVolume(VolumeInfo volume, DataStore store) { - + AsyncCallFuture future = new AsyncCallFuture(); VolumeObject vo = (VolumeObject) volume; @@ -607,11 +646,11 @@ public class VolumeServiceImpl implements VolumeService { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)) .setContext(context); - + dataObjectMgr.createAsync(volume, store, caller, true); return future; } - + protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); VolumeObject vo = (VolumeObject)context.volume; @@ -624,7 +663,7 @@ public class VolumeServiceImpl implements VolumeService { context.future.complete(res); return null; } - + @Override public AsyncCallFuture resize(VolumeInfo volume) { @@ -645,12 +684,12 @@ public class VolumeServiceImpl implements VolumeService { volume.getDataStore().getDriver().resize(volume, caller); return future; } - + protected Void resizeVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); AsyncCallFuture future = context.future; VolumeInfo volume = (VolumeInfo)context.volume; - + if (result.isFailed()) { try { volume.processEvent(Event.OperationFailed); @@ -662,7 +701,7 @@ public class VolumeServiceImpl implements VolumeService { future.complete(res); return null; } - + try { volume.processEvent(Event.OperationSuccessed); } catch(Exception e) { @@ -672,13 +711,137 @@ public class VolumeServiceImpl implements VolumeService { future.complete(res); return null; } - + VolumeApiResult res = new VolumeApiResult(volume); future.complete(res); - + return null; } - - + + @Override + public void handleVolumeSync(DataStore store) { + if (store == null) { + s_logger.warn("Huh? ssHost is null"); + return; + } + long storeId = store.getId(); + Long zoneId = store.getScope().getScopeId(); + + + Map volumeInfos = listVolume(store); + if (volumeInfos == null) { + return; + } + + List dbVolumes = _volumeStoreDao.listByStoreId(storeId); + List toBeDownloaded = new ArrayList(dbVolumes); + for (VolumeDataStoreVO volumeStore : dbVolumes){ + VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId()); + //Exists then don't download + if (volumeInfos.containsKey(volume.getId())){ + TemplateProp volInfo = volumeInfos.remove(volume.getId()); + toBeDownloaded.remove(volumeStore); + s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table"); + if (volumeStore.getDownloadState() != Status.DOWNLOADED) { + volumeStore.setErrorString(""); + } + if (volInfo.isCorrupted()) { + volumeStore.setDownloadState(Status.DOWNLOAD_ERROR); + String msg = "Volume " + volume.getUuid() + " is corrupted on image store "; + volumeStore.setErrorString(msg); + s_logger.info("msg"); + if (volumeStore.getDownloadUrl() == null) { + msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in image store: " + volumeStore.getDataStoreId(); + s_logger.warn(msg); + } else { + toBeDownloaded.add(volumeStore); + } + + } else { // Put them in right status + volumeStore.setDownloadPercent(100); + volumeStore.setDownloadState(Status.DOWNLOADED); + volumeStore.setInstallPath(volInfo.getInstallPath()); + volumeStore.setSize(volInfo.getSize()); + volumeStore.setPhysicalSize(volInfo.getPhysicalSize()); + volumeStore.setLastUpdated(new Date()); + _volumeStoreDao.update(volumeStore.getId(), volumeStore); + + if (volume.getSize() == 0) { + // Set volume size in volumes table + volume.setSize(volInfo.getSize()); + _volumeDao.update(volumeStore.getVolumeId(), volume); + } + + if (volInfo.getSize() > 0) { + try { + String url = _volumeStoreDao.findByVolumeId(volume.getId()).getDownloadUrl(); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), + com.cloud.configuration.Resource.ResourceType.secondary_storage, + volInfo.getSize() - UriUtils.getRemoteSize(url)); + } catch (ResourceAllocationException e) { + s_logger.warn(e.getMessage()); + _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), + volume.getPodId(), e.getMessage(), e.getMessage()); + } finally { + _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), + com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); + } + } + } + continue; + } + // Volume is not on secondary but we should download. + if (volumeStore.getDownloadState() != Status.DOWNLOADED) { + s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly"); + toBeDownloaded.add(volumeStore); + } + } + + //Download volumes which haven't been downloaded yet. + if (toBeDownloaded.size() > 0) { + for (VolumeDataStoreVO volumeHost : toBeDownloaded) { + if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download + continue; + } + s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName()); + //TODO: pass a callback later + _dlMonitor.downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); + } + } + + //Delete volumes which are not present on DB. + for (Long uniqueName : volumeInfos.keySet()) { + TemplateProp vInfo = volumeInfos.get(uniqueName); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getUri(), vInfo.getInstallPath()); + try { + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); + } catch (AgentUnavailableException e) { + String err = "Failed to delete " + vInfo.getTemplateName() + " on image store " + storeId + " which isn't in the database"; + s_logger.error(err); + return; + } + + String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId + " since it isn't in the database"; + s_logger.info(description); + } + + } + + private Map listVolume(DataStore store) { + ListVolumeCommand cmd = new ListVolumeCommand(store.getUri()); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd); + if (answer != null && answer.getResult()) { + ListVolumeAnswer tanswer = (ListVolumeAnswer)answer; + return tanswer.getTemplateInfo(); + } else { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Can not list volumes for image store " + store.getId()); + } + } + + return null; + } } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 362e0a53e53..706c9ef5670 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -215,7 +215,7 @@ import com.cloud.storage.Volume; import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.TemplateLocation; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -2381,7 +2381,7 @@ ServerResource { return new Answer(cmd, false, " Failed to create storage pool"); } - Map tInfo = new HashMap(); + Map tInfo = new HashMap(); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, storagepool.getCapacity(), storagepool.getUsed(), tInfo); diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index a626e31f458..7d8d90c7b61 100755 --- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -114,7 +114,7 @@ import com.cloud.resource.hypervisor.HypervisorResource; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; @@ -458,7 +458,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { setupHeartBeat(pool.getUuid()); OvmStoragePool.Details d = OvmStoragePool.getDetailsByUuid(_conn, pool.getUuid()); - Map tInfo = new HashMap(); + Map tInfo = new HashMap(); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, d.totalSpace, d.freeSpace, tInfo); return answer; } catch (Exception e) { diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index a50dff6382c..ae7cf298e97 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -74,7 +74,7 @@ import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @@ -357,7 +357,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); } - return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); + return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); } @Override @@ -398,7 +398,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa txn = Transaction.open(Transaction.CLOUD_DB); txn.close(); } - return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); + return new ModifyStoragePoolAnswer(cmd, storagePool.getCapacity(), 0, new HashMap()); } @Override @@ -449,9 +449,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa List volumes = _mockVolumeDao.findByStorageIdAndType(storage.getId(), MockVolumeType.VOLUME); - Map templateInfos = new HashMap(); + Map templateInfos = new HashMap(); for (MockVolumeVO volume : volumes) { - templateInfos.put(volume.getId(), new TemplateInfo(volume.getName(), volume.getPath() + templateInfos.put(volume.getId(), new TemplateProp(volume.getName(), volume.getPath() .replaceAll(storage.getMountPoint(), ""), volume.getSize(), volume.getSize(), true, false)); } txn.commit(); @@ -492,9 +492,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa List templates = _mockVolumeDao.findByStorageIdAndType(storage.getId(), MockVolumeType.TEMPLATE); - Map templateInfos = new HashMap(); + Map templateInfos = new HashMap(); for (MockVolumeVO template : templates) { - templateInfos.put(template.getName(), new TemplateInfo(template.getName(), template.getPath() + templateInfos.put(template.getName(), new TemplateProp(template.getName(), template.getPath() .replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false)); } txn.commit(); diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java index 46df50c2133..8a03c4b9598 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentRoutingResource.java @@ -51,7 +51,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Networks.RouterPrivateIpStrategy; import com.cloud.simulator.MockVMVO; import com.cloud.storage.Storage.StorageResourceType; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.utils.Pair; import com.cloud.vm.VirtualMachine.State; @@ -168,7 +168,7 @@ public class AgentRoutingResource extends AgentStorageResource { } private StartupStorageCommand initializeLocalSR() { - Map tInfo = new HashMap(); + Map tInfo = new HashMap(); StoragePoolInfo poolInfo = _simMgr.getLocalStorage(hostGuid); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 634827b6468..4079d0d65b5 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -210,7 +210,7 @@ import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.storage.resource.StoragePoolResource; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.utils.DateUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; @@ -3137,7 +3137,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa DatastoreSummary summary = new DatastoreMO(getServiceContext(), morDatastore).getSummary(); long capacity = summary.getCapacity(); long available = summary.getFreeSpace(); - Map tInfo = new HashMap(); + Map tInfo = new HashMap(); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo); return answer; } catch (Throwable e) { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c50f13ce7e5..046827d79b7 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -233,7 +233,7 @@ import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -5287,7 +5287,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.warn(msg); return new Answer(cmd, false, msg); } - Map tInfo = new HashMap(); + Map tInfo = new HashMap(); ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(cmd, capacity, available, tInfo); return answer; } catch (XenAPIException e) { diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index e84eab42941..d1b079d05e6 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -25,6 +25,16 @@ cloud-engine-storage-image ${project.version} + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + org.apache.cloudstack + cloud-engine-storage-snapshot + ${project.version} + mysql mysql-connector-java diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index d52af65279c..46c87b7c66d 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -118,11 +119,10 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { TemplateObject tData = (TemplateObject)data; _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); } else if (data.getType() == DataObjectType.VOLUME) { - VolumeVO vol = this.volumeDao.findById(data.getId()); - VolumeInfo volInfo = (VolumeInfo)data; + VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); + _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 7ab0d3e9301..7f5b9c4b333 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -32,6 +32,16 @@ cloud-engine-storage-image ${project.version} + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + org.apache.cloudstack + cloud-engine-storage-snapshot + ${project.version} + install diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 0d84f589d83..50a82cc8793 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -118,11 +119,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { TemplateObject tData = (TemplateObject)data; _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); } else if (data.getType() == DataObjectType.VOLUME) { - VolumeVO vol = this.volumeDao.findById(data.getId()); - VolumeInfo volInfo = (VolumeInfo)data; + VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); + _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index e4d5ac29ed8..d9eab9b45e5 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -25,6 +25,16 @@ cloud-engine-storage-image ${project.version} + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + org.apache.cloudstack + cloud-engine-storage-snapshot + ${project.version} + mysql mysql-connector-java diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 27ebbe5c5e7..6254ccef6a6 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -25,6 +25,16 @@ cloud-engine-storage-image ${project.version} + + org.apache.cloudstack + cloud-engine-storage-volume + ${project.version} + + + org.apache.cloudstack + cloud-engine-storage-snapshot + ${project.version} + mysql mysql-connector-java diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 36fd5fbbe0e..e539e5c6ba3 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -35,6 +35,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -118,11 +119,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { TemplateObject tData = (TemplateObject)data; _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); } else if (data.getType() == DataObjectType.VOLUME) { - VolumeVO vol = this.volumeDao.findById(data.getId()); - VolumeInfo volInfo = (VolumeInfo)data; + VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(vol, vol.getDataCenterId(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase())); + _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 78b26bb69fd..3b1a768f0fe 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1993,15 +1993,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId()); // Verify that there are no live snapshot, template, volume on the image store to be deleted - List snapshots = _snapshotStoreDao.listLiveByStoreId(storeId); + List snapshots = _snapshotStoreDao.listByStoreId(storeId); if ( snapshots != null && snapshots.size() > 0 ){ throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!"); } - List volumes = _volumeStoreDao.listLiveByStoreId(storeId); + List volumes = _volumeStoreDao.listByStoreId(storeId); if ( volumes != null && volumes.size() > 0 ){ throw new CloudRuntimeException("Cannot delete image store with active volumes backup!"); } - List templates = _templateStoreDao.listLiveByStoreId(storeId); + List templates = _templateStoreDao.listByStoreId(storeId); if ( templates != null && templates.size() > 0 ){ throw new CloudRuntimeException("Cannot delete image store with active templates backup!"); } diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 8e979abdfd9..3eb223325cb 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -18,6 +18,7 @@ package com.cloud.storage.download; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; @@ -26,9 +27,15 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -52,6 +59,8 @@ import com.cloud.exception.ConnectionException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.resource.ResourceManager; import com.cloud.storage.Storage; import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateHostVO; @@ -117,57 +126,68 @@ public class DownloadListener implements Listener { public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString(); - private HostVO sserver; - private HostVO ssAgent; + private HostVO _sserver; + private HostVO _ssAgent; - private VMTemplateVO template; - private VolumeVO volume; - private boolean downloadActive = true; + private VMTemplateVO _template; + private VolumeVO _volume; + private boolean _downloadActive = true; - private VolumeHostDao volumeHostDao; + private VolumeHostDao _volumeHostDao; + private VolumeDataStoreDao _volumeStoreDao; private VolumeDao _volumeDao; private StorageManager _storageMgr; - private VMTemplateHostDao vmTemplateHostDao; + private VMTemplateHostDao _vmTemplateHostDao; private TemplateDataStoreDao _vmTemplateStoreDao; private VMTemplateDao _vmTemplateDao; private ResourceLimitService _resourceLimitMgr; private AccountManager _accountMgr; private AlertManager _alertMgr; - private final DownloadMonitorImpl downloadMonitor; + private final DownloadMonitorImpl _downloadMonitor; - private DownloadState currState; + private DownloadState _currState; - private DownloadCommand cmd; + private DownloadCommand _cmd; - private Timer timer; + private Timer _timer; - private StatusTask statusTask; - private TimeoutTask timeoutTask; - private Date lastUpdated = new Date(); - private String jobId; + private StatusTask _statusTask; + private TimeoutTask _timeoutTask; + private Date _lastUpdated = new Date(); + private String _jobId; - private final Map stateMap = new HashMap(); - private Long templateHostId; - private Long volumeHostId; + private final Map _stateMap = new HashMap(); + private Long _templateHostId; + private Long _volumeHostId; - private DataStore sstore; - private Long templateStoreId; - private AsyncCompletionCallback callback; + private DataStore _sstore; + private Long _templateStoreId; + private Long _volumeStoreId; + private AsyncCompletionCallback _callback; + + @Inject + private ResourceManager _resourceMgr; + @Inject + private TemplateService _imageSrv; + @Inject + private DataStoreManager _storeMgr; + @Inject + private VolumeService _volumeSrv; public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) { - this.ssAgent = ssAgent; - this.sserver = host; - this.template = template; - this.vmTemplateHostDao = dao; - this.downloadMonitor = downloadMonitor; - this.cmd = cmd; - this.templateHostId = templHostId; + this._ssAgent = ssAgent; + this._sserver = host; + this._template = template; + this._vmTemplateHostDao = dao; + this._downloadMonitor = downloadMonitor; + this._cmd = cmd; + this._templateHostId = templHostId; initStateMachine(); - this.currState=getState(Status.NOT_DOWNLOADED.toString()); - this.timer = _timer; - this.timeoutTask = new TimeoutTask(this); - this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); + this._currState=getState(Status.NOT_DOWNLOADED.toString()); + this._timer = _timer; + this._timeoutTask = new TimeoutTask(this); + this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); this._vmTemplateDao = templateDao; this._resourceLimitMgr = _resourceLimitMgr; this._accountMgr = _accountMgr; @@ -177,63 +197,64 @@ public class DownloadListener implements Listener { // TODO: this constructor should be the one used for template only, remove other template constructor later public DownloadListener(HostVO ssAgent, DataStore store, VMTemplateVO template, Timer _timer, TemplateDataStoreDao dao, Long templStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback callback) { - this.ssAgent = ssAgent; - this.sstore = store; - this.template = template; + this._ssAgent = ssAgent; + this._sstore = store; + this._template = template; this._vmTemplateStoreDao = dao; - this.downloadMonitor = downloadMonitor; - this.cmd = cmd; - this.templateStoreId = templStoreId; + this._downloadMonitor = downloadMonitor; + this._cmd = cmd; + this._templateStoreId = templStoreId; initStateMachine(); - this.currState=getState(Status.NOT_DOWNLOADED.toString()); - this.timer = _timer; - this.timeoutTask = new TimeoutTask(this); - this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); + this._currState=getState(Status.NOT_DOWNLOADED.toString()); + this._timer = _timer; + this._timeoutTask = new TimeoutTask(this); + this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); this._vmTemplateDao = templateDao; this._resourceLimitMgr = _resourceLimitMgr; this._accountMgr = _accountMgr; this._alertMgr = _alertMgr; - this.callback = callback; + this._callback = callback; updateDatabase(Status.NOT_DOWNLOADED, ""); } - public DownloadListener(HostVO ssAgent, HostVO host, VolumeVO volume, Timer _timer, VolumeHostDao dao, Long volHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) { - this.ssAgent = ssAgent; - this.sserver = host; - this.volume = volume; - this.volumeHostDao = dao; - this.downloadMonitor = downloadMonitor; - this.cmd = cmd; - this.volumeHostId = volHostId; + public DownloadListener(HostVO ssAgent, DataStore store, VolumeVO volume, Timer _timer, VolumeDataStoreDao dao, Long volStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback callback) { + this._ssAgent = ssAgent; + this._sstore = store; + this._volume = volume; + this._volumeStoreDao = dao; + this._downloadMonitor = downloadMonitor; + this._cmd = cmd; + this._volumeStoreId = volStoreId; initStateMachine(); - this.currState=getState(Status.NOT_DOWNLOADED.toString()); - this.timer = _timer; - this.timeoutTask = new TimeoutTask(this); - this.timer.schedule(timeoutTask, 3*STATUS_POLL_INTERVAL); + this._currState=getState(Status.NOT_DOWNLOADED.toString()); + this._timer = _timer; + this._timeoutTask = new TimeoutTask(this); + this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); this._volumeDao = volumeDao; this._storageMgr = storageMgr; this._resourceLimitMgr = _resourceLimitMgr; this._accountMgr = _accountMgr; this._alertMgr = _alertMgr; + this._callback = callback; updateDatabase(Status.NOT_DOWNLOADED, ""); } public void setCurrState(VMTemplateHostVO.Status currState) { - this.currState = getState(currState.toString()); + this._currState = getState(currState.toString()); } private void initStateMachine() { - stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this)); - stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this)); - stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this)); - stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this)); - stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this)); + _stateMap.put(Status.NOT_DOWNLOADED.toString(), new NotDownloadedState(this)); + _stateMap.put(Status.DOWNLOADED.toString(), new DownloadCompleteState(this)); + _stateMap.put(Status.DOWNLOAD_ERROR.toString(), new DownloadErrorState(this)); + _stateMap.put(Status.DOWNLOAD_IN_PROGRESS.toString(), new DownloadInProgressState(this)); + _stateMap.put(Status.ABANDONED.toString(), new DownloadAbandonedState(this)); } private DownloadState getState(String stateName) { - return stateMap.get(stateName); + return _stateMap.get(stateName); } public void sendCommand(RequestType reqType) { @@ -243,10 +264,10 @@ public class DownloadListener implements Listener { } try { DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType); - if (template == null){ + if (_template == null){ dcmd.setResourceType(ResourceType.VOLUME); } - downloadMonitor.send(ssAgent.getId(), dcmd, this); + _downloadMonitor.send(_ssAgent.getId(), dcmd, this); } catch (AgentUnavailableException e) { s_logger.debug("Send command failed", e); setDisconnected(); @@ -264,63 +285,63 @@ public class DownloadListener implements Listener { } public void logDisconnect() { - if (template != null){ - s_logger.warn("Unable to monitor download progress of " + template.getName() + " at host " + sserver.getName()); + if (_template != null){ + s_logger.warn("Unable to monitor download progress of " + _template.getName() + " at host " + _sserver.getName()); }else { - s_logger.warn("Unable to monitor download progress of " + volume.getName() + " at host " + sserver.getName()); + s_logger.warn("Unable to monitor download progress of " + _volume.getName() + " at host " + _sserver.getName()); } } public synchronized void updateDatabase(Status state, String errorString) { - if (template != null){ - VMTemplateHostVO vo = vmTemplateHostDao.createForUpdate(); + if (_template != null){ + VMTemplateHostVO vo = _vmTemplateHostDao.createForUpdate(); vo.setDownloadState(state); vo.setLastUpdated(new Date()); vo.setErrorString(errorString); - vmTemplateHostDao.update(getTemplateHostId(), vo); + _vmTemplateHostDao.update(getTemplateHostId(), vo); }else { - VolumeHostVO vo = volumeHostDao.createForUpdate(); + VolumeHostVO vo = _volumeHostDao.createForUpdate(); vo.setDownloadState(state); vo.setLastUpdated(new Date()); vo.setErrorString(errorString); - volumeHostDao.update(getVolumeHostId(), vo); + _volumeHostDao.update(getVolumeHostId(), vo); } } public void log(String message, Level level) { - if (template != null){ - s_logger.log(level, message + ", template=" + template.getName() + " at host " + sserver.getName()); + if (_template != null){ + s_logger.log(level, message + ", template=" + _template.getName() + " at host " + _sserver.getName()); }else { - s_logger.log(level, message + ", volume=" + volume.getName() + " at host " + sserver.getName()); + s_logger.log(level, message + ", volume=" + _volume.getName() + " at host " + _sserver.getName()); } } private Long getTemplateHostId() { - if (templateHostId == null){ - VMTemplateHostVO templHost = vmTemplateHostDao.findByHostTemplate(sserver.getId(), template.getId()); - templateHostId = templHost.getId(); + if (_templateHostId == null){ + VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId()); + _templateHostId = templHost.getId(); } - return templateHostId; + return _templateHostId; } private Long getTemplateStoreId() { - if (templateStoreId == null){ - TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(sstore.getId(), template.getId()); - templateStoreId = templStore.getId(); + if (_templateStoreId == null){ + TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(_sstore.getId(), _template.getId()); + _templateStoreId = templStore.getId(); } - return templateStoreId; + return _templateStoreId; } private Long getVolumeHostId() { - if (volumeHostId == null){ - VolumeHostVO volHost = volumeHostDao.findByHostVolume(sserver.getId(), volume.getId()); - volumeHostId = volHost.getId(); + if (_volumeHostId == null){ + VolumeHostVO volHost = _volumeHostDao.findByHostVolume(_sserver.getId(), _volume.getId()); + _volumeHostId = volHost.getId(); } - return volumeHostId; + return _volumeHostId; } public DownloadListener(DownloadMonitorImpl monitor) { - downloadMonitor = monitor; + _downloadMonitor = monitor; } @@ -350,15 +371,15 @@ public class DownloadListener implements Listener { } private synchronized void transition(DownloadEvent event, Object evtObj) { - if (currState == null) { + if (_currState == null) { return; } - String prevName = currState.getName(); - String nextState = currState.handleEvent(event, evtObj); + String prevName = _currState.getName(); + String nextState = _currState.handleEvent(event, evtObj); if (nextState != null) { - currState = getState(nextState); - if (currState != null) { - currState.onEntry(prevName, event, evtObj); + _currState = getState(nextState); + if (_currState != null) { + _currState.onEntry(prevName, event, evtObj); } else { throw new CloudRuntimeException("Invalid next state: currState="+prevName+", evt="+event + ", next=" + nextState); } @@ -368,7 +389,7 @@ public class DownloadListener implements Listener { } public synchronized void updateDatabase(DownloadAnswer answer) { - if (template != null){ + if (_template != null){ TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); updateBuilder.setDownloadState(answer.getDownloadStatus()); @@ -380,40 +401,58 @@ public class DownloadListener implements Listener { updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column + Status dndStatus = answer.getDownloadStatus(); + // if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){ + if ( _callback != null ){ + if (dndStatus == Status.DOWNLOAD_ERROR){ + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSucess(false); + result.setResult("Download template failed"); + _callback.complete(result); + } else if (dndStatus == Status.DOWNLOADED){ + CreateCmdResult result = new CreateCmdResult(null, null); + _callback.complete(result); + } + } + else{ + // no callback specified, just update state here + if (dndStatus == Status.DOWNLOAD_ERROR){ + updateBuilder.setState(ObjectInDataStoreStateMachine.State.Failed); + } else if (dndStatus == Status.DOWNLOAD_IN_PROGRESS){ + updateBuilder.setState(ObjectInDataStoreStateMachine.State.Creating2); + } else if (dndStatus == Status.DOWNLOADED){ + updateBuilder.setState(ObjectInDataStoreStateMachine.State.Ready); + } + } + // } _vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder); if (answer.getCheckSum() != null) { VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); templateDaoBuilder.setChecksum(answer.getCheckSum()); - _vmTemplateDao.update(template.getId(), templateDaoBuilder); + _vmTemplateDao.update(_template.getId(), templateDaoBuilder); } if (answer.getTemplateSize() > 0) { //long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId(); - long accountId = template.getAccountId(); + long accountId = _template.getAccountId(); try { _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), com.cloud.configuration.Resource.ResourceType.secondary_storage, - answer.getTemplateSize() - UriUtils.getRemoteSize(template.getUrl())); + answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl())); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, sserver.getDataCenterId(), + _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _sserver.getDataCenterId(), null, e.getMessage(), e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } } - // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column - Status dndStatus = answer.getDownloadStatus(); - if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){ - if ( callback != null ){ - CreateCmdResult result = new CreateCmdResult(null, null); - callback.complete(result); - } - } + } else { - VolumeHostVO updateBuilder = volumeHostDao.createForUpdate(); + VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); updateBuilder.setDownloadState(answer.getDownloadStatus()); updateBuilder.setLastUpdated(new Date()); @@ -424,25 +463,25 @@ public class DownloadListener implements Listener { updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - volumeHostDao.update(getVolumeHostId(), updateBuilder); + _volumeHostDao.update(getVolumeHostId(), updateBuilder); // Update volume size in Volume table. VolumeVO updateVolume = _volumeDao.createForUpdate(); updateVolume.setSize(answer.getTemplateSize()); - _volumeDao.update(volume.getId(), updateVolume); + _volumeDao.update(_volume.getId(), updateVolume); if (answer.getTemplateSize() > 0) { try { - String url = volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl(); - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), + String url = _volumeHostDao.findByVolumeId(_volume.getId()).getDownloadUrl(); + _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(_volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage, answer.getTemplateSize() - UriUtils.getRemoteSize(url)); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), - volume.getPodId(), e.getMessage(), e.getMessage()); + _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _volume.getDataCenterId(), + _volume.getPodId(), e.getMessage(), e.getMessage()); } finally { - _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), + _resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } } @@ -474,8 +513,12 @@ public class DownloadListener implements Listener { @Override public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { - - downloadMonitor.handleSysTemplateDownload(agent); + List hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId()); + HypervisorType hostHyper = agent.getHypervisorType(); + if (hypers.contains(hostHyper)) { + return; + } + _imageSrv.handleSysTemplateDownload(hostHyper, agent.getDataCenterId()); } /* This can be removed since else if ( cmd instanceof StartupStorageCommand) { @@ -488,16 +531,20 @@ public class DownloadListener implements Listener { } }*/ else if ( cmd instanceof StartupSecondaryStorageCommand ) { - downloadMonitor.handleSync(agent.getDataCenterId()); + List imageStores = this._storeMgr.getImageStoresByScope(new ZoneScope(agent.getDataCenterId())); + for (DataStore store : imageStores){ + _volumeSrv.handleVolumeSync(store); + _imageSrv.handleTemplateSync(store); + } } } public void setCommand(DownloadCommand _cmd) { - this.cmd = _cmd; + this._cmd = _cmd; } public DownloadCommand getCommand() { - return cmd; + return _cmd; } @@ -506,63 +553,63 @@ public class DownloadListener implements Listener { } public void setJobId(String _jobId) { - this.jobId = _jobId; + this._jobId = _jobId; } public String getJobId() { - return jobId; + return _jobId; } public void scheduleStatusCheck(RequestType request) { - if (statusTask != null) statusTask.cancel(); + if (_statusTask != null) _statusTask.cancel(); - statusTask = new StatusTask(this, request); - timer.schedule(statusTask, STATUS_POLL_INTERVAL); + _statusTask = new StatusTask(this, request); + _timer.schedule(_statusTask, STATUS_POLL_INTERVAL); } public void scheduleTimeoutTask(long delay) { - if (timeoutTask != null) timeoutTask.cancel(); + if (_timeoutTask != null) _timeoutTask.cancel(); - timeoutTask = new TimeoutTask(this); - timer.schedule(timeoutTask, delay); + _timeoutTask = new TimeoutTask(this); + _timer.schedule(_timeoutTask, delay); if (s_logger.isDebugEnabled()) { log("Scheduling timeout at " + delay + " ms", Level.DEBUG); } } public void scheduleImmediateStatusCheck(RequestType request) { - if (statusTask != null) statusTask.cancel(); - statusTask = new StatusTask(this, request); - timer.schedule(statusTask, SMALL_DELAY); + if (_statusTask != null) _statusTask.cancel(); + _statusTask = new StatusTask(this, request); + _timer.schedule(_statusTask, SMALL_DELAY); } public boolean isDownloadActive() { - return downloadActive; + return _downloadActive; } public void cancelStatusTask() { - if (statusTask != null) statusTask.cancel(); + if (_statusTask != null) _statusTask.cancel(); } public Date getLastUpdated() { - return lastUpdated; + return _lastUpdated; } public void setLastUpdated() { - lastUpdated = new Date(); + _lastUpdated = new Date(); } public void setDownloadInactive(Status reason) { - downloadActive=false; - if (template != null){ - downloadMonitor.handleDownloadEvent(sserver, template, reason); + _downloadActive=false; + if (_template != null){ + _downloadMonitor.handleDownloadEvent(_sserver, _template, reason); }else { - downloadMonitor.handleDownloadEvent(sserver, volume, reason); + _downloadMonitor.handleDownloadEvent(_sserver, _volume, reason); } } public void cancelTimeoutTask() { - if (timeoutTask != null) timeoutTask.cancel(); + if (_timeoutTask != null) _timeoutTask.cancel(); } public void logDownloadStart() { diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index b20973352d5..b5a3f8592b9 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.storage.download; -import java.util.Map; - import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -28,7 +26,6 @@ import com.cloud.host.HostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.template.TemplateInfo; import com.cloud.utils.component.Manager; /** @@ -37,23 +34,17 @@ import com.cloud.utils.component.Manager; */ public interface DownloadMonitor extends Manager{ - public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); public void cancelAllDownloads(Long templateId); - public void handleTemplateSync(DataStore store); - public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer) throws StorageUnavailableException; - void handleSysTemplateDownload(HostVO hostId); + //void addSystemVMTemplatesToHost(HostVO host, Map templateInfos); - void handleSync(Long dcId); + //public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format); - void addSystemVMTemplatesToHost(HostVO host, Map templateInfos); - - boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format); - - void handleVolumeSync(HostVO ssHost); + public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 82665e361a1..507d57531fe 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -18,12 +18,9 @@ package com.cloud.storage.download; import java.net.URI; import java.net.URISyntaxException; -import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.Timer; import java.util.concurrent.ConcurrentHashMap; @@ -33,19 +30,17 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.ZoneScope; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.Proxy; @@ -53,16 +48,10 @@ import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.ListTemplateAnswer; -import com.cloud.agent.api.storage.ListTemplateCommand; -import com.cloud.agent.api.storage.ListVolumeAnswer; -import com.cloud.agent.api.storage.ListVolumeCommand; - import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.event.EventTypes; @@ -70,9 +59,7 @@ import com.cloud.event.UsageEventUtils; import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; -import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -80,12 +67,10 @@ import com.cloud.resource.ResourceManager; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; -import com.cloud.storage.SwiftVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.StoragePoolHostDao; @@ -101,12 +86,10 @@ import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; -import com.cloud.storage.template.TemplateInfo; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; -import com.cloud.utils.UriUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.JoinBuilder; @@ -117,14 +100,10 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.SecondaryStorageVm; import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.UserVmManager; -import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; -import edu.emory.mathcs.backport.java.util.Collections; - -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -152,6 +131,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject VolumeHostDao _volumeHostDao; @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject AlertManager _alertMgr; @Inject protected SwiftManager _swiftMgr; @@ -206,6 +187,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor final Map _listenerTemplateMap = new ConcurrentHashMap(); final Map _listenerMap = new ConcurrentHashMap(); final Map _listenerVolumeMap = new ConcurrentHashMap(); + final Map _listenerVolMap = new ConcurrentHashMap(); public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException { @@ -256,7 +238,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor public boolean isTemplateUpdateable(Long templateId, Long storeId) { List downloadsInProgress = - _vmTemplateStoreDao.listByTemplateStoreStatus(templateId, storeId, ObjectInDataStoreStateMachine.State.Creating, ObjectInDataStoreStateMachine.State.Creating2, ObjectInDataStoreStateMachine.State.Ready); + _vmTemplateStoreDao.listByTemplateStoreDownloadStatus(templateId, storeId, Status.DOWNLOAD_IN_PROGRESS, Status.DOWNLOADED ); return (downloadsInProgress.size() == 0); } @@ -370,7 +352,11 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor TemplateDataStoreVO vmTemplateStore = null; vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); - // we should already persist one entry in template_store_ref table, so vmTemplateStore should not be null + if (vmTemplateStore == null) { + // This method can be invoked other places, for example, handleTemplateSync, in that case, vmTemplateStore may be null + vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); + _vmTemplateStoreDao.persist(vmTemplateStore); + } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { downloadJobExists = true; } @@ -420,42 +406,33 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Override - public boolean downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); if (isTemplateUpdateable(templateId, store.getId())) { if ( template != null && template.getUrl() != null ){ initiateTemplateDownload(template, store, callback); } } - return true; } + @Override - public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format) { - - List ssHosts = _ssvmMgr.listAllTypesSecondaryStorageHostsInOneZone(zoneId); - Collections.shuffle(ssHosts); - HostVO ssHost = ssHosts.get(0); - downloadVolumeToStorage(volume, ssHost, url, checkSum, format); - return true; - } - - private void downloadVolumeToStorage(VolumeVO volume, HostVO sserver, String url, String checkSum, ImageFormat format) { + public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback) { boolean downloadJobExists = false; - VolumeHostVO volumeHost = null; + VolumeDataStoreVO volumeHost = null; - volumeHost = _volumeHostDao.findByHostVolume(sserver.getId(), volume.getId()); + volumeHost = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId()); if (volumeHost == null) { - volumeHost = new VolumeHostVO(sserver.getId(), volume.getId(), sserver.getDataCenterId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, + volumeHost = new VolumeDataStoreVO(store.getId(), volume.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, url, checkSum, format); - _volumeHostDao.persist(volumeHost); + _volumeStoreDao.persist(volumeHost); } else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) { downloadJobExists = true; } Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes(); - String secUrl = sserver.getStorageUrl(); + String secUrl = store.getUri(); if(volumeHost != null) { start(); DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format); @@ -465,45 +442,35 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor dcmd.setResourceType(ResourceType.VOLUME); } - HostVO ssvm = _ssvmMgr.pickSsvmHost(sserver); - if( ssvm == null ) { - s_logger.warn("There is no secondary storage VM for secondary storage host " + sserver.getName()); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + if( ssAhost == null ) { + s_logger.warn("There is no secondary storage VM for image store " + store.getName()); return; } - DownloadListener dl = new DownloadListener(ssvm, sserver, volume, _timer, _volumeHostDao, volumeHost.getId(), - this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr); + DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(), + this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback); if (downloadJobExists) { dl.setCurrState(volumeHost.getDownloadState()); } DownloadListener old = null; - synchronized (_listenerVolumeMap) { - old = _listenerVolumeMap.put(volumeHost, dl); + synchronized (_listenerVolMap) { + old = _listenerVolMap.put(volumeHost, dl); } if( old != null ) { old.abandon(); } try { - send(ssvm.getId(), dcmd, dl); + send(ssAhost.getId(), dcmd, dl); } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + sserver.getName(), e); + s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e); dl.setDisconnected(); dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } } } -/* - private void initiateTemplateDownload(Long templateId, DataStore store) { - VMTemplateVO template = _templateDao.findById(templateId); - if (template != null && (template.getUrl() != null)) { - //find all storage hosts and tell them to initiate download - downloadTemplateToStorage(template, store); - } - - } - */ @DB public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { @@ -583,62 +550,18 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor txn.commit(); } - @Override - public void handleSysTemplateDownload(HostVO host) { - List hypers = _resourceMgr.listAvailHypervisorInZone(host.getId(), host.getDataCenterId()); - HypervisorType hostHyper = host.getHypervisorType(); - if (hypers.contains(hostHyper)) { - return; - } - - Set toBeDownloaded = new HashSet(); - List ssHosts = this.storeMgr.getImageStoresByScope(new ZoneScope(host.getDataCenterId())); - if (ssHosts == null || ssHosts.isEmpty()){ - return; - } - /* - List ssHosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.SecondaryStorage, host.getDataCenterId()); - if (ssHosts == null || ssHosts.isEmpty()) { - return; - } - */ - /*Download all the templates in zone with the same hypervisortype*/ - for ( DataStore ssHost : ssHosts) { - List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); - for (VMTemplateVO rtngTmplt : rtngTmplts) { - if (rtngTmplt.getHypervisorType() == hostHyper) { - toBeDownloaded.add(rtngTmplt); - } - } - - for (VMTemplateVO builtinTmplt : defaultBuiltin) { - if (builtinTmplt.getHypervisorType() == hostHyper) { - toBeDownloaded.add(builtinTmplt); - } - } - - for (VMTemplateVO template: toBeDownloaded) { - VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(ssHost.getId(), template.getId()); - if (tmpltHost == null || tmpltHost.getDownloadState() != Status.DOWNLOADED) { - //TODO: pass callback here - initiateTemplateDownload(template, ssHost, null); - } - } - } - } - + /* @Override - public void addSystemVMTemplatesToHost(HostVO host, Map templateInfos){ + public void addSystemVMTemplatesToHost(HostVO host, Map templateInfos){ if ( templateInfos == null ) { return; } Long hostId = host.getId(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); for ( VMTemplateVO tmplt : rtngTmplts ) { - TemplateInfo tmpltInfo = templateInfos.get(tmplt.getUniqueName()); + TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName()); if ( tmpltInfo == null ) { continue; } @@ -651,354 +574,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } } + */ - @Override - public void handleSync(Long dcId) { - if (dcId != null) { - List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId); - for (HostVO ssHost : ssHosts) { - //handleTemplateSync(ssHost); - handleVolumeSync(ssHost); - } - } - List imageStores = this.storeMgr.getImageStoresByScope(new ZoneScope(dcId)); - for (DataStore store : imageStores){ - handleTemplateSync(store); - } - } - private Map listTemplate(DataStore ssHost) { - ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri()); - HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost); - Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd); - if (answer != null && answer.getResult()) { - ListTemplateAnswer tanswer = (ListTemplateAnswer)answer; - return tanswer.getTemplateInfo(); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("can not list template for secondary storage host " + ssHost.getId()); - } - } - - return null; - } - - private Map listVolume(HostVO ssHost) { - ListVolumeCommand cmd = new ListVolumeCommand(ssHost.getStorageUrl()); - Answer answer = _agentMgr.sendToSecStorage(ssHost, cmd); - if (answer != null && answer.getResult()) { - ListVolumeAnswer tanswer = (ListVolumeAnswer)answer; - return tanswer.getTemplateInfo(); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Can not list volumes for secondary storage host " + ssHost.getId()); - } - } - - return null; - } - - private Map listTemplate(SwiftVO swift) { - if (swift == null) { - return null; - } - ListTemplateCommand cmd = new ListTemplateCommand(swift.toSwiftTO()); - Answer answer = _agentMgr.sendToSSVM(null, cmd); - if (answer != null && answer.getResult()) { - ListTemplateAnswer tanswer = (ListTemplateAnswer) answer; - return tanswer.getTemplateInfo(); - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("can not list template for swift " + swift); - } - } - return null; - } - - @Override - public void handleVolumeSync(HostVO ssHost) { - if (ssHost == null) { - s_logger.warn("Huh? ssHost is null"); - return; - } - long sserverId = ssHost.getId(); - if (!(ssHost.getType() == Host.Type.SecondaryStorage || ssHost.getType() == Host.Type.LocalSecondaryStorage)) { - s_logger.warn("Huh? Agent id " + sserverId + " is not secondary storage host"); - return; - } - - Map volumeInfos = listVolume(ssHost); - if (volumeInfos == null) { - return; - } - - List dbVolumes = _volumeHostDao.listBySecStorage(sserverId); - List toBeDownloaded = new ArrayList(dbVolumes); - for (VolumeHostVO volumeHost : dbVolumes){ - VolumeVO volume = _volumeDao.findById(volumeHost.getVolumeId()); - //Exists then don't download - if (volumeInfos.containsKey(volume.getId())){ - TemplateInfo volInfo = volumeInfos.remove(volume.getId()); - toBeDownloaded.remove(volumeHost); - s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume host table"); - if (volumeHost.getDownloadState() != Status.DOWNLOADED) { - volumeHost.setErrorString(""); - } - if (volInfo.isCorrupted()) { - volumeHost.setDownloadState(Status.DOWNLOAD_ERROR); - String msg = "Volume " + volume.getUuid() + " is corrupted on secondary storage "; - volumeHost.setErrorString(msg); - s_logger.info("msg"); - if (volumeHost.getDownloadUrl() == null) { - msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in secondary storage: " + volumeHost.getHostId(); - s_logger.warn(msg); - } else { - toBeDownloaded.add(volumeHost); - } - - } else { // Put them in right status - volumeHost.setDownloadPercent(100); - volumeHost.setDownloadState(Status.DOWNLOADED); - volumeHost.setInstallPath(volInfo.getInstallPath()); - volumeHost.setSize(volInfo.getSize()); - volumeHost.setPhysicalSize(volInfo.getPhysicalSize()); - volumeHost.setLastUpdated(new Date()); - _volumeHostDao.update(volumeHost.getId(), volumeHost); - - if (volume.getSize() == 0) { - // Set volume size in volumes table - volume.setSize(volInfo.getSize()); - _volumeDao.update(volumeHost.getVolumeId(), volume); - } - - if (volInfo.getSize() > 0) { - try { - String url = _volumeHostDao.findByVolumeId(volume.getId()).getDownloadUrl(); - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - volInfo.getSize() - UriUtils.getRemoteSize(url)); - } catch (ResourceAllocationException e) { - s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), - volume.getPodId(), e.getMessage(), e.getMessage()); - } finally { - _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - } - } - continue; - } - // Volume is not on secondary but we should download. - if (volumeHost.getDownloadState() != Status.DOWNLOADED) { - s_logger.info("Volume Sync did not find " + volume.getName() + " ready on server " + sserverId + ", will request download to start/resume shortly"); - toBeDownloaded.add(volumeHost); - } - } - - //Download volumes which haven't been downloaded yet. - if (toBeDownloaded.size() > 0) { - for (VolumeHostVO volumeHost : toBeDownloaded) { - if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download - continue; - } - s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + ssHost.getName()); - downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), ssHost, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat()); - } - } - - //Delete volumes which are not present on DB. - for (Long uniqueName : volumeInfos.keySet()) { - TemplateInfo vInfo = volumeInfos.get(uniqueName); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(ssHost.getStorageUrl(), vInfo.getInstallPath()); - try { - _agentMgr.sendToSecStorage(ssHost, dtCommand, null); - } catch (AgentUnavailableException e) { - String err = "Failed to delete " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " which isn't in the database"; - s_logger.error(err); - return; - } - - String description = "Deleted volume " + vInfo.getTemplateName() + " on secondary storage " + sserverId + " since it isn't in the database"; - s_logger.info(description); - } - } - - @Override - public void handleTemplateSync(DataStore ssStore) { - if (ssStore == null) { - s_logger.warn("Huh? image store is null"); - return; - } - long storeId = ssStore.getId(); - Long zoneId = ssStore.getScope().getScopeId(); - - Map templateInfos = listTemplate(ssStore); - if (templateInfos == null) { - return; - } - - Set toBeDownloaded = new HashSet(); - List allTemplates = null; - if (zoneId == null){ - // region wide store - allTemplates = _templateDao.listAll(); - } - else{ - // zone wide store - allTemplates = _templateDao.listAllInZone(zoneId); - } - List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); - - if (rtngTmplts != null) { - for (VMTemplateVO rtngTmplt : rtngTmplts) { - if (!allTemplates.contains(rtngTmplt)) { - allTemplates.add(rtngTmplt); - } - } - } - - if (defaultBuiltin != null) { - for (VMTemplateVO builtinTmplt : defaultBuiltin) { - if (!allTemplates.contains(builtinTmplt)) { - allTemplates.add(builtinTmplt); - } - } - } - - toBeDownloaded.addAll(allTemplates); - - for (VMTemplateVO tmplt : allTemplates) { - String uniqueName = tmplt.getUniqueName(); - TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); - if (templateInfos.containsKey(uniqueName)) { - TemplateInfo tmpltInfo = templateInfos.remove(uniqueName); - toBeDownloaded.remove(tmplt); - if (tmpltStore != null) { - s_logger.info("Template Sync found " + uniqueName + " already in the template host table"); - if (tmpltStore.getDownloadState() != Status.DOWNLOADED) { - tmpltStore.setErrorString(""); - } - if (tmpltInfo.isCorrupted()) { - tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR); - String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId(); - tmpltStore.setErrorString(msg); - s_logger.info("msg"); - if (tmplt.getUrl() == null) { - msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId(); - s_logger.warn(msg); - } else { - toBeDownloaded.add(tmplt); - } - - } else { - tmpltStore.setDownloadPercent(100); - tmpltStore.setDownloadState(Status.DOWNLOADED); - tmpltStore.setInstallPath(tmpltInfo.getInstallPath()); - tmpltStore.setSize(tmpltInfo.getSize()); - tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); - tmpltStore.setLastUpdated(new Date()); - - if (tmpltInfo.getSize() > 0) { - long accountId = tmplt.getAccountId(); - try { - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl())); - } catch (ResourceAllocationException e) { - s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, - null, e.getMessage(), e.getMessage()); - } finally { - _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - } - } - _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore); - } else { - tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); - tmpltStore.setSize(tmpltInfo.getSize()); - tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); - _vmTemplateStoreDao.persist(tmpltStore); - this.associateTemplateToZone(tmplt.getId(), zoneId); - } - - continue; - } - if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) { - s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly"); - - } else if (tmpltStore == null) { - s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly"); - TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); - _vmTemplateStoreDao.persist(templtStore); - this.associateTemplateToZone(tmplt.getId(), zoneId); - } - - } - - if (toBeDownloaded.size() > 0) { - /* Only download templates whose hypervirsor type is in the zone */ - List availHypers = _clusterDao.getAvailableHypervisorInZone(zoneId); - if (availHypers.isEmpty()) { - /* - * This is for cloudzone, local secondary storage resource - * started before cluster created - */ - availHypers.add(HypervisorType.KVM); - } - /* Baremetal need not to download any template */ - availHypers.remove(HypervisorType.BareMetal); - availHypers.add(HypervisorType.None); // bug 9809: resume ISO - // download. - for (VMTemplateVO tmplt : toBeDownloaded) { - if (tmplt.getUrl() == null) { // If url is null we can't - // initiate the download - continue; - } - // if this is private template, and there is no record for this - // template in this sHost, skip - if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) { - VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(storeId, tmplt.getId()); - if (tmpltHost == null) { - continue; - } - } - if (availHypers.contains(tmplt.getHypervisorType())) { - if (_swiftMgr.isSwiftEnabled()) { - if (_swiftMgr.isTemplateInstalled(tmplt.getId())) { - continue; - } - } - s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + ssStore.getName()); - //TODO: we should pass a callback here - initiateTemplateDownload(tmplt, ssStore, null); - } - } - } - - for (String uniqueName : templateInfos.keySet()) { - TemplateInfo tInfo = templateInfos.get(uniqueName); - List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); - //check if there is any Vm using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(ssStore.getUri(), tInfo.getInstallPath()); - try { - HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore); - _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); - } catch (AgentUnavailableException e) { - String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database"; - s_logger.error(err); - return; - } - - String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database"; - s_logger.info(description); - } - } - } @Override public void cancelAllDownloads(Long templateId) { @@ -1067,30 +645,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } - // persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case, - // we will associate the template to all the zones. - private void associateTemplateToZone(long templateId, Long zoneId){ - List dcs = new ArrayList(); - if (zoneId != null ){ - dcs.add(zoneId); - } - else{ - List zones = _dcDao.listAll(); - for (DataCenterVO zone : zones){ - dcs.add(zone.getId()); - } - } - for (Long id : dcs) { - VMTemplateZoneVO tmpltZoneVO = _vmTemplateZoneDao.findByZoneTemplate(id, templateId); - if (tmpltZoneVO == null) { - tmpltZoneVO = new VMTemplateZoneVO(id, templateId, new Date()); - _vmTemplateZoneDao.persist(tmpltZoneVO); - } else { - tmpltZoneVO.setLastUpdated(new Date()); - _vmTemplateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); - } - } - } } diff --git a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java index 8f25514180c..02463d2f7dc 100644 --- a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java +++ b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java @@ -50,7 +50,7 @@ import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.template.TemplateConstants; -import com.cloud.storage.template.TemplateInfo; +import com.cloud.storage.template.TemplateProp; public class DummySecondaryStorageResource extends ServerResourceBase implements ServerResource { @@ -113,7 +113,7 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements public StartupCommand[] initialize() { final StartupStorageCommand cmd = new StartupStorageCommand("dummy", StoragePoolType.NetworkFilesystem, 1024*1024*1024*100L, - new HashMap()); + new HashMap()); cmd.setResourceType(Storage.StorageResourceType.SECONDARY_STORAGE); cmd.setIqn(null); @@ -173,12 +173,12 @@ public class DummySecondaryStorageResource extends ServerResourceBase implements return _useServiceVm; } - public Map getDefaultSystemVmTemplateInfo() { + public Map getDefaultSystemVmTemplateInfo() { List tmplts = _tmpltDao.listAllSystemVMTemplates(); - Map tmpltInfo = new HashMap(); + Map tmpltInfo = new HashMap(); if (tmplts != null) { for (VMTemplateVO tmplt : tmplts) { - TemplateInfo routingInfo = new TemplateInfo(tmplt.getUniqueName(), TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, false, false); + TemplateProp routingInfo = new TemplateProp(tmplt.getUniqueName(), TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, false, false); tmpltInfo.put(tmplt.getUniqueName(), routingInfo); } } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 709288eca00..06cf6ac7fed 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -36,7 +36,7 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.log4j.Logger; @@ -75,7 +75,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te @Inject AgentManager _agentMgr; @Inject DataStoreManager storeMgr; - @Inject ImageService imageService; + @Inject TemplateService imageService; @Inject ImageDataFactory imageFactory; @Inject TemplateManager templateMgr; diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index 19ba3b52734..af5488076e6 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -35,7 +35,7 @@ import com.cloud.utils.Pair; /** * TemplateManager manages the templates stored on secondary storage. It is responsible for creating private/public templates. */ -public interface TemplateManager extends TemplateService{ +public interface TemplateManager extends TemplateApiService{ /** * Prepares a template for vm creation for a certain storage pool. diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index f4ad36e64ed..77c686073be 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -58,7 +58,7 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; @@ -187,8 +187,8 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @Component -@Local(value={TemplateManager.class, TemplateService.class}) -public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateService { +@Local(value={TemplateManager.class, TemplateApiService.class}) +public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService { private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); @Inject VMTemplateDao _tmpltDao; @Inject VMTemplateHostDao _tmpltHostDao; @@ -246,7 +246,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject SnapshotDataFactory snapshotFactory; @Inject - ImageService imageSvr; + TemplateService imageSvr; @Inject DataStoreManager dataStoreMgr; @Inject From b81fa6d9eaf096fedce9c6907e83c1770eac1584 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 11 Apr 2013 17:49:32 -0700 Subject: [PATCH 022/303] add copy template to cache store --- .../api/storage/AbstractDownloadCommand.java | 2 +- .../PrimaryStorageDownloadCommand.java | 9 ++ .../subsystem/api/storage/DataObject.java | 4 + .../subsystem/api/storage/DataStore.java | 1 + .../api/storage/DataStoreDriver.java | 1 + .../subsystem/api/storage/DataStoreTO.java | 23 +++ .../engine/subsystem/api/storage/DataTO.java | 28 ++++ .../api/storage}/EndPointSelector.java | 5 +- .../subsystem/api/storage/TemplateInfo.java | 1 + .../manager/StorageCacheManagerImpl.java | 64 +++++++- .../motion/AncientDataMotionStrategy.java | 30 +++- .../storage/image/store/ImageStoreImpl.java | 6 +- .../storage/image/store/TemplateObject.java | 48 +++--- .../storage/test/ChildTestConfiguration.java | 2 +- .../storage/test/volumeServiceTest.java | 2 +- .../storage/snapshot/SnapshotObject.java | 14 ++ .../cloudstack/storage/command/CopyCmd.java | 39 +++-- .../datastore/ObjectInDataStoreManager.java | 2 + .../ObjectInDataStoreManagerImpl.java | 26 ++- .../endpoint/DefaultEndPointSelector.java | 1 + .../cloudstack/storage/to/ImageStoreTO.java | 20 ++- .../storage/to/PrimaryDataStoreTO.java | 9 +- .../cloudstack/storage/to/TemplateTO.java | 27 +++- .../cloudstack/storage/to/VolumeTO.java | 8 +- .../datastore/PrimaryDataStoreImpl.java | 6 + .../storage/volume/VolumeObject.java | 20 ++- .../storage/volume/VolumeServiceImpl.java | 4 +- .../resource/XenServerStorageResource.java | 153 ++++++++++++++++-- .../CloudStackImageStoreDriverImpl.java | 6 + .../driver/S3ImageStoreDriverImpl.java | 6 + .../driver/SampleImageStoreDriverImpl.java | 8 +- .../driver/SwiftImageStoreDriverImpl.java | 6 + .../CloudStackPrimaryDataStoreDriverImpl.java | 6 + .../SamplePrimaryDataStoreDriverImpl.java | 8 +- .../SamplePrimaryDataStoreLifeCycleImpl.java | 2 +- .../SolidfirePrimaryDataStoreDriver.java | 6 + .../cloud/template/TemplateManagerImpl.java | 3 +- 37 files changed, 529 insertions(+), 77 deletions(-) create mode 100644 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java create mode 100644 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java rename engine/{storage/src/org/apache/cloudstack/storage/endpoint => api/src/org/apache/cloudstack/engine/subsystem/api/storage}/EndPointSelector.java (81%) diff --git a/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java b/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java index 04b3d4360d5..248a41902ac 100644 --- a/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/AbstractDownloadCommand.java @@ -28,7 +28,7 @@ public abstract class AbstractDownloadCommand extends ssCommand { protected AbstractDownloadCommand() { } - protected AbstractDownloadCommand(String name, String url, ImageFormat format, long accountId) { + protected AbstractDownloadCommand(String name, String url, ImageFormat format, Long accountId) { assert(url != null); url = url.replace('\\', '/'); diff --git a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java b/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java index 8d955bb1c63..b0d0fdf87eb 100644 --- a/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/PrimaryStorageDownloadCommand.java @@ -34,7 +34,16 @@ public class PrimaryStorageDownloadCommand extends AbstractDownloadCommand { String primaryStorageUrl; protected PrimaryStorageDownloadCommand() { + } + + public PrimaryStorageDownloadCommand(String url, StoragePool pool, int wait) { + super(null, url, null, null); + this.poolId = pool.getId(); + this.poolUuid = pool.getUuid(); + this.primaryPool = new StorageFilerTO(pool); + setWait(wait); + } public PrimaryStorageDownloadCommand(String name, String url, ImageFormat format, long accountId, StoragePool pool, int wait) { super(name, url, format, accountId); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index 0827cf6b674..9bb14c78fa3 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -20,13 +20,17 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import com.cloud.agent.api.Answer; + public interface DataObject { public long getId(); public String getUri(); + public DataTO getTO(); public DataStore getDataStore(); public Long getSize(); public DataObjectType getType(); public DiskFormat getFormat(); public String getUuid(); public void processEvent(ObjectInDataStoreStateMachine.Event event); + public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java index 10f869c39fe..d20167bbba0 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java @@ -26,4 +26,5 @@ public interface DataStore { String getName(); DataObject create(DataObject obj); boolean delete(DataObject obj); + DataStoreTO getTO(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java index cf5759b2924..f79d349ff0d 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java @@ -31,4 +31,5 @@ public interface DataStoreDriver { public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback); public boolean canCopy(DataObject srcData, DataObject destData); public void resize(DataObject data, AsyncCompletionCallback callback); + public DataTO getTO(DataObject data); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java new file mode 100644 index 00000000000..5886bdec366 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.engine.subsystem.api.storage; + +public interface DataStoreTO { + public DataStoreRole getRole(); +} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java new file mode 100644 index 00000000000..cd437459d84 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.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; + +public interface DataTO { + public DataObjectType getObjectType(); + public DataStoreTO getDataStore(); + /** + * @return + */ + String getPath(); +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java similarity index 81% rename from engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java index 6910eb6a401..fe3a1b713ba 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/EndPointSelector.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java @@ -16,13 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.endpoint; +package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.List; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; public interface EndPointSelector { public EndPoint select(DataObject srcData, DataObject destData); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java index 8e03503911e..99de1da07fa 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java @@ -19,4 +19,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface TemplateInfo extends DataObject { + public String getUniqueName(); } 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 index f943ed49f82..c51ce6e6b5e 100644 --- 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 @@ -20,20 +20,30 @@ package org.apache.cloudstack.storage.cache.manager; import java.util.List; import java.util.Map; +import java.util.concurrent.ExecutionException; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; +import org.apache.log4j.Logger; import com.cloud.utils.component.Manager; public class StorageCacheManagerImpl implements StorageCacheManager, Manager { + private static final Logger s_logger = Logger + .getLogger(StorageCacheManagerImpl.class); @Inject List storageCacheAllocator; @Inject @@ -101,14 +111,62 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { // TODO Auto-generated method stub return true; } + + + + private class CreateCacheObjectContext extends AsyncRpcConext { + final AsyncCallFuture future; + /** + * @param callback + */ + public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { + super(callback); + this.future = future; + } + + } @Override public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - //AsyncCallFuture<> - //dataMotionSvr.copyAsync(data, objOnCacheStore, callback); - // TODO Auto-generated method stub + AsyncCallFuture future = new AsyncCallFuture(); + CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setContext(context); + + + CommandResult result = null; + try { + objOnCacheStore.processEvent(Event.CreateOnlyRequested); + + dataMotionSvr.copyAsync(data, objOnCacheStore, caller); + result = future.get(); + + if (result.isFailed()) { + cacheStore.delete(data); + } else { + objOnCacheStore.processEvent(Event.OperationSuccessed); + } + } catch (InterruptedException e) { + s_logger.debug("create cache storage failed: " + e.toString()); + } catch (ExecutionException e) { + s_logger.debug("create cache storage failed: " + e.toString()); + } catch (Exception e) { + s_logger.debug("create cache storage failed: " + e.toString()); + } finally { + if (result == null) { + cacheStore.delete(data); + } + } + return null; } + + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, + CreateCacheObjectContext context) { + AsyncCallFuture future = context.future; + future.complete(callback.getResult()); + return null; + } } \ No newline at end of file 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 index 1d164cdddf7..efc2f99973b 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -29,9 +29,13 @@ 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.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CopyCmd; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -51,6 +55,8 @@ 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.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.SwiftTO; @@ -93,6 +99,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { private static final Logger s_logger = Logger .getLogger(AncientDataMotionStrategy.class); @Inject + EndPointSelector selector; + @Inject TemplateManager templateMgr; @Inject VolumeHostDao volumeHostDao; @@ -124,6 +132,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject + StorageCacheManager cacheMgr; @Override public boolean canHandle(DataObject srcData, DataObject destData) { @@ -178,10 +188,22 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } private Answer copyTemplate(DataObject srcData, DataObject destData) { - VMTemplateVO template = this.templateDao.findById(srcData.getId()); - templateMgr.prepareTemplateForCreate(template, - (StoragePool) destData.getDataStore()); - return null; + String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); + int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); + if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + //need to copy it to image cache store + DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); + CopyCmd cmd = new CopyCmd(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); + EndPoint ep = selector.select(cacheData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } else { + //handle copy it to cache store + CopyCmd cmd = new CopyCmd(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } } protected Answer copyFromSnapshot(DataObject snapObj, DataObject volObj) { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 7e143cb6f06..4cd70caa311 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; 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.SnapshotInfo; @@ -164,7 +165,10 @@ public class ImageStoreImpl implements ImageStoreEntity { return imageDataStoreVO.getProtocol(); } - + @Override + public DataStoreTO getTO() { + return null; + } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index b6c20046c1c..2025d27d45d 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; 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.TemplateEvent; @@ -30,15 +31,16 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.image.manager.ImageDataManager; +import org.apache.cloudstack.storage.to.TemplateTO; import org.apache.log4j.Logger; +import com.cloud.agent.api.Answer; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.utils.storage.encoding.EncodingType; public class TemplateObject implements TemplateInfo { private static final Logger s_logger = Logger @@ -83,6 +85,11 @@ public class TemplateObject implements TemplateInfo { public DataStore getDataStore() { return this.dataStore; } + + @Override + public String getUniqueName() { + return this.imageVO.getUniqueName(); + } @Override public long getId() { @@ -101,22 +108,7 @@ public class TemplateObject implements TemplateInfo { return image.getUrl(); } else { DataObjectInStore obj = ojbectInStoreMgr.findObject(this, this.dataStore); - StringBuilder builder = new StringBuilder(); - if (obj.getState() == ObjectInDataStoreStateMachine.State.Ready - || obj.getState() == ObjectInDataStoreStateMachine.State.Copying) { - - builder.append(this.dataStore.getUri()); - builder.append("&" + EncodingType.OBJTYPE + "=" + DataObjectType.TEMPLATE); - builder.append("&" + EncodingType.PATH + "=" + obj.getInstallPath()); - builder.append("&" + EncodingType.SIZE + "=" + image.getSize()); - return builder.toString(); - } else { - builder.append(this.dataStore.getUri()); - builder.append("&" + EncodingType.OBJTYPE + "=" + DataObjectType.TEMPLATE); - builder.append("&" + EncodingType.SIZE + "=" + image.getSize()); - builder.append("&" + EncodingType.PATH + "=" + image.getUrl()); - return builder.toString(); - } + return obj.getInstallPath(); } } @@ -174,10 +166,30 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(Event event) { try { - ojbectInStoreMgr.update(this, event); + ojbectInStoreMgr.update(this, event, null); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); } } + + @Override + public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { + try { + ojbectInStoreMgr.update(this, event, answer); + } catch (NoTransitionException e) { + s_logger.debug("failed to update state", e); + throw new CloudRuntimeException("Failed to update state" + e.toString()); + } + } + + @Override + public DataTO getTO() { + DataTO to = this.dataStore.getDriver().getTO(this); + if (to == null) { + to = new TemplateTO(this); + } + + return to; + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index a063bdda8ad..4b8dbb868f2 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -20,9 +20,9 @@ import java.io.IOException; import org.apache.cloudstack.acl.APIChecker; import org.apache.cloudstack.engine.service.api.OrchestrationService; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.rpc.RpcProvider; import org.apache.cloudstack.storage.HostEndpointRpcServer; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index fcb89624dde..ca641057290 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -38,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; 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.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; @@ -50,7 +51,6 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.HypervisorHostEndPoint; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.volume.db.VolumeDao2; import org.apache.cloudstack.storage.volume.db.VolumeVO; import org.mockito.Mockito; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index d10dc778092..b8a7760c783 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -24,6 +24,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; @@ -32,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.log4j.Logger; +import com.cloud.agent.api.Answer; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; @@ -220,4 +222,16 @@ public class SnapshotObject implements SnapshotInfo { public String getBackupSnapshotId() { return this.snapshot.getBackupSnapshotId(); } + + @Override + public DataTO getTO() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) { + // TODO Auto-generated method stub + + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java b/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java index 10478ef24c7..9cb225b762f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java @@ -16,30 +16,47 @@ // under the License. package org.apache.cloudstack.storage.command; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; + import com.cloud.agent.api.Command; public class CopyCmd extends Command implements StorageSubSystemCommand { - private String srcUri; - private String destUri; + private DataTO srcTO; + private DataTO destTO; + private int timeout; - public CopyCmd(String srcUri, String destUri) { + /** + * @return the timeout + */ + public int getTimeout() { + return timeout; + } + + /** + * @param timeout the timeout to set + */ + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public CopyCmd(DataTO srcUri, DataTO destUri, int timeout) { super(); - this.srcUri = srcUri; - this.destUri = destUri; + this.srcTO = srcUri; + this.destTO = destUri; + this.timeout = timeout; } - public String getDestUri() { - return this.destUri; + public DataTO getDestTO() { + return this.destTO; } - public String getSrcUri() { - return this.srcUri; + public DataTO getSrcTO() { + return this.srcTO; } @Override public boolean executeInSequence() { - // TODO Auto-generated method stub - return false; + return true; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index cb27c0271c9..26321438404 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -23,11 +23,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import com.cloud.agent.api.Answer; import com.cloud.utils.fsm.NoTransitionException; public interface ObjectInDataStoreManager { public DataObject create(DataObject template, DataStore dataStore); public DataObject get(DataObject dataObj, DataStore store); + public boolean update(DataObject vo, Event event, Answer answer) throws NoTransitionException; public boolean update(DataObject vo, Event event) throws NoTransitionException; DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index ac96c5f9f69..632860d7b94 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -29,6 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -40,7 +41,9 @@ import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.Answer; import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; @@ -148,7 +151,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } @Override - public boolean update(DataObject data, Event event) + public boolean update(DataObject data, Event event, Answer answer) throws NoTransitionException { DataObjectInStore obj = this.findObject(data, data.getDataStore()); if (obj == null) { @@ -167,11 +170,21 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao); } } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { + if (answer != null && answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(data.getDataStore().getId(), data.getId()); + templatePoolRef.setDownloadPercent(100); + templatePoolRef.setDownloadState(Status.DOWNLOADED); + templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); + templatePoolRef.setInstallPath(cpyAnswer.getPath()); + templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); + } try { - this.stateMachines.transitTo(obj, event, null, - templatePoolDao); + obj = this.findObject(data, data.getDataStore()); + this.stateMachines.transitTo(obj, event, null, + templatePoolDao); } catch (NoTransitionException e) { - throw e; + throw e; } } else { throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); @@ -254,4 +267,9 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return store; } + @Override + public boolean update(DataObject vo, Event event) throws NoTransitionException { + return this.update(vo, event, null); + } + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 772a8f29aef..ab5c5521a9e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.HypervisorHostEndPoint; diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java index eb6d0883835..5224e2e6ccb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -16,14 +16,20 @@ // under the License. package org.apache.cloudstack.storage.to; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; -public class ImageStoreTO { +public class ImageStoreTO implements DataStoreTO { private final String type; private final String uri; + private final String providerName; + private final DataStoreRole role; public ImageStoreTO(ImageStoreInfo dataStore) { this.type = dataStore.getType(); this.uri = dataStore.getUri(); + this.providerName = null; + this.role = dataStore.getRole(); } public String getType() { @@ -33,4 +39,16 @@ public class ImageStoreTO { public String getUri() { return this.uri; } + + /** + * @return the providerName + */ + public String getProviderName() { + return providerName; + } + + @Override + public DataStoreRole getRole() { + return this.role; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index aa47e8f4977..b410dd6f4e4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -16,9 +16,11 @@ // under the License. package org.apache.cloudstack.storage.to; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -public class PrimaryDataStoreTO { +public class PrimaryDataStoreTO implements DataStoreTO { private final String uuid; private final String name; private String type; @@ -45,4 +47,9 @@ public class PrimaryDataStoreTO { public String getType() { return this.type; } + + @Override + public DataStoreRole getRole() { + return DataStoreRole.Primary; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java index d7b146bd0bc..f54c2c71e1d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java @@ -16,23 +16,29 @@ // under the License. package org.apache.cloudstack.storage.to; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; -public class TemplateTO { +public class TemplateTO implements DataTO { private final String path; private final String uuid; private DiskFormat diskType; private final ImageStoreTO imageDataStore; + private final String name; public TemplateTO(TemplateInfo template) { - this.path = null; + this.path = template.getUri(); this.uuid = template.getUuid(); //this.diskType = template.getDiskType(); this.imageDataStore = new ImageStoreTO((ImageStoreInfo)template.getDataStore()); + this.name = template.getUniqueName(); } + @Override public String getPath() { return this.path; } @@ -48,4 +54,21 @@ public class TemplateTO { public ImageStoreTO getImageDataStore() { return this.imageDataStore; } + + @Override + public DataObjectType getObjectType() { + return DataObjectType.TEMPLATE; + } + + @Override + public DataStoreTO getDataStore() { + return (DataStoreTO)this.imageDataStore; + } + + /** + * @return the name + */ + public String getName() { + return name; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java index c65b6525827..162ff38cc2f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java @@ -16,12 +16,14 @@ // under the License. package org.apache.cloudstack.storage.to; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; -public class VolumeTO { +public class VolumeTO implements DataTO { private final String uuid; private final String path; private VolumeType volumeType; @@ -74,4 +76,8 @@ public class VolumeTO { public long getSize() { return this.size; } + + public DataObjectType getObjectType() { + return DataObjectType.VOLUME; + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 3266eaf5631..836f9d4a5ed 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -29,6 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -340,4 +341,9 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { public String getStorageProviderName() { return this.pdsv.getStorageProviderName(); } + + @Override + public DataStoreTO getTO() { + return null; + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 766d219261d..c2fb0cb1133 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -24,12 +24,15 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.to.VolumeTO; import org.apache.log4j.Logger; +import com.cloud.agent.api.Answer; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; @@ -162,7 +165,7 @@ public class VolumeObject implements VolumeInfo { try { Volume.Event volEvent = null; if (this.dataStore.getRole() == DataStoreRole.Image) { - ojbectInStoreMgr.update(this, event); + ojbectInStoreMgr.update(this, event, null); if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { volEvent = Volume.Event.UploadRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { @@ -331,4 +334,19 @@ public class VolumeObject implements VolumeInfo { public Long getLastPoolId() { return this.volumeVO.getLastPoolId(); } + + @Override + public DataTO getTO() { + DataTO to = this.getDataStore().getDriver().getTO(this); + if (to == null) { + to = new VolumeTO(this); + } + return to; + } + + @Override + public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) { + // TODO Auto-generated method stub + + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 2da16c1178d..d017f4f3600 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -428,7 +428,7 @@ public class VolumeServiceImpl implements VolumeService { VolumeObject vo = (VolumeObject)volume; CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, vo, pd, templateOnPrimaryStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyBaseImageCallBack(null, null)) + caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)) .setContext(context); DataObject volumeOnPrimaryStorage = pd.create(volume); @@ -439,7 +439,7 @@ public class VolumeServiceImpl implements VolumeService { } @DB - public Void copyBaseImageCallBack(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { + protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { VolumeObject vo = context.vo; CopyCommandResult result = callback.getResult(); VolumeApiResult volResult = new VolumeApiResult(vo); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 9c291491114..70c992f791f 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -28,7 +28,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.CopyCmd; @@ -40,6 +45,9 @@ import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; +import org.apache.cloudstack.storage.to.ImageStoreTO; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.TemplateTO; import org.apache.cloudstack.storage.to.VolumeTO; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -52,6 +60,8 @@ import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; @@ -601,21 +611,134 @@ public class XenServerStorageResource { } } - protected Answer execute(CopyCmd cmd) { - DecodedDataObject srcObj = null; - DecodedDataObject destObj = null; - try { - srcObj = Decoder.decode(cmd.getSrcUri()); - destObj = Decoder.decode(cmd.getDestUri()); - } catch (URISyntaxException e) { - return new Answer(cmd, false, e.toString()); - } - - - if (srcObj.getPath().startsWith("http")) { - return directDownloadHttpTemplate(cmd, srcObj, destObj); + private boolean IsISCSI(String type) { + return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type) ; + } + + private String copy_vhd_from_secondarystorage(Connection conn, String mountpoint, String sruuid, int wait) { + String nameLabel = "cloud-" + UUID.randomUUID().toString(); + String results = hypervisorResource.callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", + wait, "mountpoint", mountpoint, "sruuid", sruuid, "namelabel", nameLabel); + String errMsg = null; + if (results == null || results.isEmpty()) { + errMsg = "copy_vhd_from_secondarystorage return null"; } else { - return new Answer(cmd, false, "not implemented yet"); + String[] tmp = results.split("#"); + String status = tmp[0]; + if (status.equals("0")) { + return tmp[1]; + } else { + errMsg = tmp[1]; + } + } + String source = mountpoint.substring(mountpoint.lastIndexOf('/') + 1); + if( hypervisorResource.killCopyProcess(conn, source) ) { + destroyVDIbyNameLabel(conn, nameLabel); + } + s_logger.warn(errMsg); + throw new CloudRuntimeException(errMsg); + } + + private void destroyVDIbyNameLabel(Connection conn, String nameLabel) { + try { + Set vdis = VDI.getByNameLabel(conn, nameLabel); + if ( vdis.size() != 1 ) { + s_logger.warn("destoryVDIbyNameLabel failed due to there are " + vdis.size() + " VDIs with name " + nameLabel); + return; + } + for (VDI vdi : vdis) { + try { + vdi.destroy(conn); + } catch (Exception e) { + } + } + } catch (Exception e){ + } + } + + protected VDI getVDIbyUuid(Connection conn, String uuid) { + try { + return VDI.getByUuid(conn, uuid); + } catch (Exception e) { + String msg = "Catch Exception " + e.getClass().getName() + " :VDI getByUuid for uuid: " + uuid + " failed due to " + e.toString(); + s_logger.debug(msg); + throw new CloudRuntimeException(msg, e); + } + } + + protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { + String parentUuid = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, + "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); + + if (parentUuid == null || parentUuid.isEmpty() || parentUuid.equalsIgnoreCase("None")) { + s_logger.debug("Unable to get parent of VHD " + snapshotUuid + " in SR " + primaryStorageSRUuid); + // errString is already logged. + return null; + } + return parentUuid; + } + + protected PrimaryStorageDownloadAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { + DataStoreTO srcStore = srcData.getDataStore(); + try { + if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) { + ImageStoreTO srcImageStore = (ImageStoreTO)srcStore; + TemplateTO srcTemplate = (TemplateTO)srcData; + String storeUrl = srcImageStore.getUri(); + if (!storeUrl.startsWith("nfs")) { + return new PrimaryStorageDownloadAnswer("only nfs image cache store supported"); + } + String tmplpath = storeUrl + ":" + srcData.getPath(); + PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore(); + String poolName = destStore.getUuid(); + Connection conn = hypervisorResource.getConnection(); + + SR poolsr = null; + Set srs = SR.getByNameLabel(conn, poolName); + if (srs.size() != 1) { + String msg = "There are " + srs.size() + " SRs with same name: " + poolName; + s_logger.warn(msg); + return new PrimaryStorageDownloadAnswer(msg); + } else { + poolsr = srs.iterator().next(); + } + String pUuid = poolsr.getUuid(conn); + boolean isISCSI = IsISCSI(poolsr.getType(conn)); + String uuid = copy_vhd_from_secondarystorage(conn, tmplpath, pUuid, wait); + VDI tmpl = getVDIbyUuid(conn, uuid); + VDI snapshotvdi = tmpl.snapshot(conn, new HashMap()); + String snapshotUuid = snapshotvdi.getUuid(conn); + snapshotvdi.setNameLabel(conn, "Template " + srcTemplate.getName()); + String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI); + VDI parent = getVDIbyUuid(conn, parentuuid); + Long phySize = parent.getPhysicalUtilisation(conn); + tmpl.destroy(conn); + poolsr.scan(conn); + try{ + Thread.sleep(5000); + } catch (Exception e) { + } + return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); + } + }catch (Exception e) { + String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString(); + s_logger.warn(msg, e); + return new PrimaryStorageDownloadAnswer(msg); + } + return new PrimaryStorageDownloadAnswer("not implemented yet"); + } + + + protected Answer execute(CopyCmd cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + + if (srcData.getObjectType() == DataObjectType.TEMPLATE && destData.getDataStore().getRole() == DataStoreRole.Primary) { + //copy template to primary storage + return copyTemplateToPrimaryStorage(srcData, destData, cmd.getTimeout()); + } + + return new Answer(cmd, false, "not implemented yet"); /* String tmplturl = cmd.getUrl(); String poolName = cmd.getPoolUuid(); @@ -657,6 +780,4 @@ public class XenServerStorageResource { return new PrimaryStorageDownloadAnswer(msg); }*/ } - - } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 46c87b7c66d..692aded957c 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -29,6 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -91,6 +92,11 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub return null; } + + @Override + public DataTO getTO(DataObject data) { + return null; + } @Override public boolean revokeAccess(DataObject data, EndPoint ep) { diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 50a82cc8793..c5574d3bc0b 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -29,6 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -91,6 +92,11 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub return null; } + + @Override + public DataTO getTO(DataObject data) { + return null; + } @Override public boolean revokeAccess(DataObject data, EndPoint ep) { diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index dc2e58c99cd..4d535201b2f 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -28,11 +28,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.image.ImageStoreDriver; import com.cloud.storage.dao.VMTemplateDao; @@ -45,6 +46,11 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { VMTemplateDao imageDataDao; public SampleImageStoreDriverImpl() { } + + @Override + public DataTO getTO(DataObject data) { + return null; + } @Override public String grantAccess(DataObject data, EndPoint ep) { diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index e539e5c6ba3..8504de9a15e 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -29,6 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -91,6 +92,11 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub return null; } + + @Override + public DataTO getTO(DataObject data) { + return null; + } @Override public boolean revokeAccess(DataObject data, EndPoint ep) { diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 04869020468..412647fb993 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -28,6 +28,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -90,6 +91,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri // TODO Auto-generated method stub return null; } + + @Override + public DataTO getTO(DataObject data) { + return null; + } @Override public boolean revokeAccess(DataObject data, EndPoint ep) { diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index 67e9843c037..99b16ebd5df 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -26,7 +26,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; @@ -36,7 +38,6 @@ import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.DataObjectManager; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -58,6 +59,11 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver } + @Override + public DataTO getTO(DataObject data) { + return null; + } + private class CreateVolumeContext extends AsyncRpcConext { private final DataObject volume; /** diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java index 15bf8c1dc06..ddd64e5ec98 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -34,7 +35,6 @@ import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.cloudstack.storage.endpoint.EndPointSelector; import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; import com.cloud.agent.api.StoragePoolInfo; diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index f31126c2aeb..3916773c7f4 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -35,6 +36,11 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { // TODO Auto-generated method stub return null; } + + @Override + public DataTO getTO(DataObject data) { + return null; + } @Override public boolean revokeAccess(DataObject data, EndPoint ep) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 77c686073be..aabdaf9b22b 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -739,8 +739,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId()); assert(secondaryStorageHost != null); dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl()); - // TODO temporary hacking, hard-coded to NFS primary data store - dcmd.setPrimaryStorageUrl("nfs://" + pool.getHostAddress() + pool.getPath()); + for (int retry = 0; retry < 2; retry ++){ Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries From 2ff01a79cad58597aac2e38a06c891b13ddd6ca9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 12 Apr 2013 17:10:19 -0700 Subject: [PATCH 023/303] Rename TemplateTO/VolumeTO in cloud-engine-storage to TemplateObjectTO/VolumeObjectTO to avoid name conflicting with the one in cloud-api. --- .../cloudstack/storage/image/store/TemplateObject.java | 4 ++-- .../cloudstack/storage/test/DirectAgentTest.java | 4 ++-- .../command/CreateVolumeFromBaseImageCommand.java | 8 ++++---- .../cloudstack/storage/command/DeleteCommand.java | 2 +- .../storage/to/ImageOnPrimayDataStoreTO.java | 6 +++--- .../to/{TemplateTO.java => TemplateObjectTO.java} | 4 ++-- .../storage/to/{VolumeTO.java => VolumeObjectTO.java} | 4 ++-- .../apache/cloudstack/storage/volume/VolumeObject.java | 4 ++-- .../xen/resource/XenServerStorageResource.java | 10 +++++----- 9 files changed, 23 insertions(+), 23 deletions(-) rename engine/storage/src/org/apache/cloudstack/storage/to/{TemplateTO.java => TemplateObjectTO.java} (95%) rename engine/storage/src/org/apache/cloudstack/storage/to/{VolumeTO.java => VolumeObjectTO.java} (96%) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 2025d27d45d..7727f12d91e 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -31,7 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.image.manager.ImageDataManager; -import org.apache.cloudstack.storage.to.TemplateTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -187,7 +187,7 @@ public class TemplateObject implements TemplateInfo { public DataTO getTO() { DataTO to = this.dataStore.getDriver().getTO(this); if (to == null) { - to = new TemplateTO(this); + to = new TemplateObjectTO(this); } return to; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index 71f1beb3365..a5a4cb75877 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -25,7 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.TemplateTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -134,7 +134,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { ImageStoreTO imageStore = Mockito.mock(ImageStoreTO.class); Mockito.when(imageStore.getType()).thenReturn("http"); - TemplateTO template = Mockito.mock(TemplateTO.class); + TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class); Mockito.when(template.getPath()).thenReturn(this.getTemplateUrl()); Mockito.when(template.getImageDataStore()).thenReturn(imageStore); diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java index f4be0676b9b..db96571c552 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java @@ -19,20 +19,20 @@ package org.apache.cloudstack.storage.command; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import com.cloud.agent.api.Command; public class CreateVolumeFromBaseImageCommand extends Command implements StorageSubSystemCommand { - private final VolumeTO volume; + private final VolumeObjectTO volume; private final ImageOnPrimayDataStoreTO image; - public CreateVolumeFromBaseImageCommand(VolumeTO volume, String image) { + public CreateVolumeFromBaseImageCommand(VolumeObjectTO volume, String image) { this.volume = volume; this.image = null; } - public VolumeTO getVolume() { + public VolumeObjectTO getVolume() { return this.volume; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 5d948d19356..3f62100b832 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -18,7 +18,7 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.storage.to.VolumeTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import com.cloud.agent.api.Command; diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java index 18743d70bf2..e3909187467 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java @@ -23,11 +23,11 @@ import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; public class ImageOnPrimayDataStoreTO { private final String pathOnPrimaryDataStore; private PrimaryDataStoreTO dataStore; - private final TemplateTO template; + private final TemplateObjectTO template; public ImageOnPrimayDataStoreTO(TemplateOnPrimaryDataStoreInfo template) { this.pathOnPrimaryDataStore = template.getPath(); //this.dataStore = template.getPrimaryDataStore().getDataStoreTO(); - this.template = new TemplateTO(template.getTemplate()); + this.template = new TemplateObjectTO(template.getTemplate()); } public String getPathOnPrimaryDataStore() { @@ -38,7 +38,7 @@ public class ImageOnPrimayDataStoreTO { return this.dataStore; } - public TemplateTO getTemplate() { + public TemplateObjectTO getTemplate() { return this.template; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java similarity index 95% rename from engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java rename to engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index f54c2c71e1d..76f0d036e29 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -23,14 +23,14 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; -public class TemplateTO implements DataTO { +public class TemplateObjectTO implements DataTO { private final String path; private final String uuid; private DiskFormat diskType; private final ImageStoreTO imageDataStore; private final String name; - public TemplateTO(TemplateInfo template) { + public TemplateObjectTO(TemplateInfo template) { this.path = template.getUri(); this.uuid = template.getUuid(); //this.diskType = template.getDiskType(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java similarity index 96% rename from engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java rename to engine/storage/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 162ff38cc2f..e556a3bd95b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -23,7 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; -public class VolumeTO implements DataTO { +public class VolumeObjectTO implements DataTO { private final String uuid; private final String path; private VolumeType volumeType; @@ -31,7 +31,7 @@ public class VolumeTO implements DataTO { private PrimaryDataStoreTO dataStore; private String name; private final long size; - public VolumeTO(VolumeInfo volume) { + public VolumeObjectTO(VolumeInfo volume) { this.uuid = volume.getUuid(); this.path = volume.getUri(); //this.volumeType = volume.getType(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index c2fb0cb1133..67f75b085fb 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -29,7 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; -import org.apache.cloudstack.storage.to.VolumeTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -339,7 +339,7 @@ public class VolumeObject implements VolumeInfo { public DataTO getTO() { DataTO to = this.getDataStore().getDriver().getTO(this); if (to == null) { - to = new VolumeTO(this); + to = new VolumeObjectTO(this); } return to; } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 70c992f791f..b629377a4d8 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -47,8 +47,8 @@ import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; -import org.apache.cloudstack.storage.to.TemplateTO; -import org.apache.cloudstack.storage.to.VolumeTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; @@ -194,7 +194,7 @@ public class XenServerStorageResource { } protected Answer execute(DeleteVolumeCommand cmd) { - VolumeTO volume = null; + VolumeObjectTO volume = null; Connection conn = hypervisorResource.getConnection(); String errorMsg = null; try { @@ -216,7 +216,7 @@ public class XenServerStorageResource { } protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { - VolumeTO volume = cmd.getVolume(); + VolumeObjectTO volume = cmd.getVolume(); ImageOnPrimayDataStoreTO baseImage = cmd.getImage(); Connection conn = hypervisorResource.getConnection(); @@ -683,7 +683,7 @@ public class XenServerStorageResource { try { if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) { ImageStoreTO srcImageStore = (ImageStoreTO)srcStore; - TemplateTO srcTemplate = (TemplateTO)srcData; + TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData; String storeUrl = srcImageStore.getUri(); if (!storeUrl.startsWith("nfs")) { return new PrimaryStorageDownloadAnswer("only nfs image cache store supported"); From 2dd8e2cb975b24cb4c0fba96e86c46dbba95ecf3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 12 Apr 2013 18:22:23 -0700 Subject: [PATCH 024/303] add getStoreTO into each DataStoreDriver, and add implementation for 3 data store plugins. --- .../com/cloud/agent/api/to}/DataStoreTO.java | 5 +- api/src/com/cloud/agent/api/to/S3TO.java | 9 ++- api/src/com/cloud/agent/api/to/SwiftTO.java | 10 +++- .../src/com/cloud}/storage/DataStoreRole.java | 2 +- .../subsystem/api/storage/DataStore.java | 3 + .../api/storage/DataStoreDriver.java | 3 + .../api/storage/DataStoreManager.java | 2 + .../engine/subsystem/api/storage/DataTO.java | 2 + .../storage/datastore/db/ImageStoreVO.java | 2 +- .../storage/image/ImageDataFactoryImpl.java | 2 +- .../ImageStoreProviderManagerImpl.java | 2 +- .../storage/image/store/ImageStoreImpl.java | 12 +++- .../storage/test/volumeServiceTest.java | 2 +- .../snapshot/SnapshotDataFactoryImpl.java | 2 +- .../strategy/AncientSnapshotStrategy.java | 2 +- .../datastore/DataStoreManagerImpl.java | 2 +- .../datastore/ObjectInDataStoreManager.java | 2 +- .../ObjectInDataStoreManagerImpl.java | 2 +- .../storage/db/ObjectInDataStoreVO.java | 2 +- .../endpoint/DefaultEndPointSelector.java | 2 +- .../image/datastore/ImageStoreHelper.java | 2 +- .../storage/image/db/ImageStoreDaoImpl.java | 2 +- .../cloudstack/storage/to/ImageStoreTO.java | 40 +++++++++++--- .../storage/to/PrimaryDataStoreTO.java | 5 +- .../storage/to/TemplateObjectTO.java | 3 +- .../datastore/PrimaryDataStoreHelper.java | 2 +- .../datastore/PrimaryDataStoreImpl.java | 4 +- .../provider/DefaultHostListener.java | 2 +- .../storage/volume/VolumeDataFactoryImpl.java | 2 +- .../storage/volume/VolumeObject.java | 2 +- .../resource/XenServerStorageResource.java | 4 +- .../CloudStackImageStoreDriverImpl.java | 17 +++++- .../driver/S3ImageStoreDriverImpl.java | 26 ++++++++- .../driver/SampleImageStoreDriverImpl.java | 22 +++++--- .../driver/SwiftImageStoreDriverImpl.java | 19 ++++++- .../CloudStackPrimaryDataStoreDriverImpl.java | 16 ++++-- ...oudStackPrimaryDataStoreLifeCycleImpl.java | 2 +- .../SamplePrimaryDataStoreDriverImpl.java | 55 +++++++++++-------- .../SolidfirePrimaryDataStoreDriver.java | 23 +++++--- .../cloud/resource/ResourceManagerImpl.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 1 - .../storage/StoragePoolAutomationImpl.java | 1 - .../com/cloud/storage/VolumeManagerImpl.java | 1 - .../SecondaryStorageManagerImpl.java | 2 +- .../template/HypervisorTemplateAdapter.java | 2 +- .../cloud/template/TemplateAdapterBase.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 2 +- 47 files changed, 240 insertions(+), 91 deletions(-) rename {engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage => api/src/com/cloud/agent/api/to}/DataStoreTO.java (92%) rename {engine/api/src/org/apache/cloudstack/engine/subsystem/api => api/src/com/cloud}/storage/DataStoreRole.java (96%) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java b/api/src/com/cloud/agent/api/to/DataStoreTO.java similarity index 92% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java rename to api/src/com/cloud/agent/api/to/DataStoreTO.java index 5886bdec366..9014f8e2b81 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreTO.java +++ b/api/src/com/cloud/agent/api/to/DataStoreTO.java @@ -16,7 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.engine.subsystem.api.storage; +package com.cloud.agent.api.to; + +import com.cloud.storage.DataStoreRole; + public interface DataStoreTO { public DataStoreRole getRole(); diff --git a/api/src/com/cloud/agent/api/to/S3TO.java b/api/src/com/cloud/agent/api/to/S3TO.java index d556cb6d05d..10207288185 100644 --- a/api/src/com/cloud/agent/api/to/S3TO.java +++ b/api/src/com/cloud/agent/api/to/S3TO.java @@ -18,9 +18,10 @@ package com.cloud.agent.api.to; import java.util.Date; +import com.cloud.storage.DataStoreRole; import com.cloud.utils.S3Utils; -public final class S3TO implements S3Utils.ClientOptions { +public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { private Long id; private String uuid; @@ -249,4 +250,10 @@ public final class S3TO implements S3Utils.ClientOptions { this.created = created; } + @Override + public DataStoreRole getRole() { + return DataStoreRole.Image; + } + + } diff --git a/api/src/com/cloud/agent/api/to/SwiftTO.java b/api/src/com/cloud/agent/api/to/SwiftTO.java index 32742c7d0e3..e1697f91041 100644 --- a/api/src/com/cloud/agent/api/to/SwiftTO.java +++ b/api/src/com/cloud/agent/api/to/SwiftTO.java @@ -16,7 +16,9 @@ // under the License. package com.cloud.agent.api.to; -public class SwiftTO { +import com.cloud.storage.DataStoreRole; + +public class SwiftTO implements DataStoreTO { Long id; String url; String account; @@ -54,5 +56,11 @@ public class SwiftTO { return key; } + @Override + public DataStoreRole getRole() { + return DataStoreRole.Image; + } + + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreRole.java b/api/src/com/cloud/storage/DataStoreRole.java similarity index 96% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreRole.java rename to api/src/com/cloud/storage/DataStoreRole.java index a45ca7a6c8e..0448d29e75e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreRole.java +++ b/api/src/com/cloud/storage/DataStoreRole.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.engine.subsystem.api.storage; +package com.cloud.storage; import com.cloud.utils.exception.CloudRuntimeException; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java index d20167bbba0..c0570a9148d 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java @@ -16,6 +16,9 @@ // under the License. package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.storage.DataStoreRole; + public interface DataStore { DataStoreDriver getDriver(); DataStoreRole getRole(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java index f79d349ff0d..e4986d675e0 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java @@ -22,6 +22,8 @@ import java.util.Set; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import com.cloud.agent.api.to.DataStoreTO; + public interface DataStoreDriver { public String grantAccess(DataObject data, EndPoint ep); public boolean revokeAccess(DataObject data, EndPoint ep); @@ -32,4 +34,5 @@ public interface DataStoreDriver { public boolean canCopy(DataObject srcData, DataObject destData); public void resize(DataObject data, AsyncCompletionCallback callback); public DataTO getTO(DataObject data); + public DataStoreTO getStoreTO(DataStore store); } 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 1a36c8ca45d..096a1fd1497 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 @@ -21,6 +21,8 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.List; import java.util.Map; +import com.cloud.storage.DataStoreRole; + public interface DataStoreManager { public DataStore getDataStore(long storeId, DataStoreRole role); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java index cd437459d84..9e268943865 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.agent.api.to.DataStoreTO; + public interface DataTO { public DataObjectType getObjectType(); public DataStoreTO getDataStore(); 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 5503df069dd..39b74d00e77 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,10 +28,10 @@ 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.DataStoreRole; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import com.cloud.utils.db.GenericDao; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java index a7b9c42eec0..37204bf0386 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java @@ -25,7 +25,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; @@ -33,6 +32,7 @@ import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; 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 a1096d31fad..c14e2d91af6 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,7 +28,6 @@ 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; @@ -41,6 +40,7 @@ import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.db.SearchCriteria.Op; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 4cd70caa311..4989b2629a2 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -18,14 +18,13 @@ */ package org.apache.cloudstack.storage.image.store; +import java.util.Date; import java.util.Set; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; 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.SnapshotInfo; @@ -37,6 +36,8 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.storage.encoding.EncodingType; @@ -132,6 +133,11 @@ public class ImageStoreImpl implements ImageStoreEntity { return this.imageDataStoreVO.getUuid(); } + public Date getCreated(){ + return this.imageDataStoreVO.getCreated(); + } + + @Override public DataObject create(DataObject obj) { DataObject object = objectInStoreMgr.create(obj, this); @@ -165,6 +171,8 @@ public class ImageStoreImpl implements ImageStoreEntity { return imageDataStoreVO.getProtocol(); } + + @Override public DataStoreTO getTO() { return null; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index ca641057290..64d2143ba8c 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -36,7 +36,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; 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.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; @@ -73,6 +72,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceState; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java index 6a7edc2302c..ff96a1957a5 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java @@ -25,7 +25,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; @@ -33,6 +32,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDao; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java index ce2786b80b9..944c477d2c7 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java @@ -30,7 +30,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; 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.PrimaryDataStoreDriver; @@ -58,6 +57,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.StoragePool; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index adc7250cc73..fb1460400b9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -25,12 +25,12 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.utils.exception.CloudRuntimeException; @Component diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index 26321438404..876a06694b5 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -20,10 +20,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import com.cloud.agent.api.Answer; +import com.cloud.storage.DataStoreRole; import com.cloud.utils.fsm.NoTransitionException; public interface ObjectInDataStoreManager { diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 632860d7b94..69db87232c5 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -23,7 +23,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; @@ -42,6 +41,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplatePoolDao; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index 7b44de0ce91..fb8c93ceedc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -31,9 +31,9 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index ab5c5521a9e..2d03c44b972 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -28,7 +28,6 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; @@ -40,6 +39,7 @@ import org.springframework.stereotype.Component; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.utils.db.DB; import com.cloud.utils.db.SearchCriteria2; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index a4d3db93718..64f85910a3e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -23,13 +23,13 @@ import java.util.Map; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import com.cloud.utils.exception.CloudRuntimeException; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index ee0782217b8..2300649bd86 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -24,7 +24,6 @@ import java.util.Map; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; @@ -32,6 +31,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java index 5224e2e6ccb..a9d95e812e1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -16,26 +16,32 @@ // under the License. package org.apache.cloudstack.storage.to; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.storage.DataStoreRole; + public class ImageStoreTO implements DataStoreTO { - private final String type; - private final String uri; - private final String providerName; - private final DataStoreRole role; + private String type; + private String uri; + private String providerName; + private DataStoreRole role; + + public ImageStoreTO(){ + + } + public ImageStoreTO(ImageStoreInfo dataStore) { this.type = dataStore.getType(); this.uri = dataStore.getUri(); this.providerName = null; this.role = dataStore.getRole(); } - + public String getType() { return this.type; } - + public String getUri() { return this.uri; } @@ -47,8 +53,26 @@ public class ImageStoreTO implements DataStoreTO { return providerName; } + + public void setType(String type) { + this.type = type; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public void setRole(DataStoreRole role) { + this.role = role; + } + @Override public DataStoreRole getRole() { return this.role; } + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index b410dd6f4e4..cf9448bd73a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -16,10 +16,11 @@ // under the License. package org.apache.cloudstack.storage.to; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.storage.DataStoreRole; + public class PrimaryDataStoreTO implements DataStoreTO { private final String uuid; private final String name; diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 76f0d036e29..513a1dd1b8f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -17,12 +17,13 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; +import com.cloud.agent.api.to.DataStoreTO; + public class TemplateObjectTO implements DataTO { private final String path; private final String uuid; diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java index c5f7a1b2352..d131008d65e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java @@ -25,7 +25,6 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; @@ -41,6 +40,7 @@ import com.cloud.alert.AlertManager; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 836f9d4a5ed..0feefd0528c 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -28,8 +28,6 @@ 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.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -47,8 +45,10 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index f2cb1c45c82..fcb5c323183 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -21,7 +21,6 @@ package org.apache.cloudstack.storage.datastore.provider; import javax.inject.Inject; 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.HypervisorHostListener; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -32,6 +31,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.ModifyStoragePoolAnswer; import com.cloud.agent.api.ModifyStoragePoolCommand; import com.cloud.alert.AlertManager; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.dao.StoragePoolHostDao; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java index 3019cf2e64a..2929d3881e5 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java @@ -24,12 +24,12 @@ 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.DataStore; 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.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 67f75b085fb..34e080d5d52 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -23,7 +23,6 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -34,6 +33,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index b629377a4d8..1cd53351185 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -31,8 +31,6 @@ import java.util.Set; import java.util.UUID; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreTO; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; @@ -62,7 +60,9 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; +import com.cloud.storage.DataStoreRole; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.DecodedDataStore; diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 692aded957c..af6a3b63492 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -35,7 +35,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -43,10 +45,12 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.SnapshotVO; @@ -92,12 +96,23 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub return null; } - + @Override public DataTO getTO(DataObject data) { return null; } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + ImageStoreImpl nfsStore = (ImageStoreImpl)store; + ImageStoreTO nfsTO = new ImageStoreTO(); + nfsTO.setProviderName("CloudStack"); + nfsTO.setRole(DataStoreRole.Image); + nfsTO.setUri(nfsStore.getUri()); + return nfsTO; + } + @Override public boolean revokeAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index c5574d3bc0b..5f33a492027 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -19,10 +19,12 @@ package org.apache.cloudstack.storage.datastore.driver; import java.util.List; +import java.util.Map; import java.util.Set; import javax.inject.Inject; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -34,7 +36,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -43,6 +47,7 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.host.HostVO; @@ -77,6 +82,8 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { @Inject DownloadMonitor _downloadMonitor; @Inject VMTemplateHostDao _vmTemplateHostDao; + @Inject + ImageStoreDetailsDao _imageStoreDetailsDao; @Inject VolumeDao volumeDao; @Inject VolumeHostDao volumeHostDao; @Inject HostDao hostDao; @@ -92,12 +99,29 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub return null; } - + @Override public DataTO getTO(DataObject data) { return null; } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + ImageStoreImpl imgStore = (ImageStoreImpl)store; + Map details = _imageStoreDetailsDao.getDetails(imgStore.getId()); + return new S3TO(imgStore.getId(), imgStore.getUuid(), details.get(ApiConstants.S3_ACCESS_KEY), + details.get(ApiConstants.S3_SECRET_KEY), + details.get(ApiConstants.S3_END_POINT), + details.get(ApiConstants.S3_BUCKET_NAME), + Boolean.parseBoolean(details.get(ApiConstants.S3_HTTPS_FLAG)), + Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TIMEOUT)), + Integer.valueOf(details.get(ApiConstants.S3_MAX_ERROR_RETRY)), + Integer.valueOf(details.get(ApiConstants.S3_SOCKET_TIMEOUT)), + imgStore.getCreated()); + + } + @Override public boolean revokeAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index 4d535201b2f..acf679679dc 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -36,6 +36,7 @@ import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.image.ImageStoreDriver; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.dao.VMTemplateDao; //http-read-only based image store @@ -46,12 +47,19 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { VMTemplateDao imageDataDao; public SampleImageStoreDriverImpl() { } - + @Override public DataTO getTO(DataObject data) { return null; } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + // TODO Auto-generated method stub + return null; + } + @Override public String grantAccess(DataObject data, EndPoint ep) { return data.getUri(); @@ -79,7 +87,7 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { callback.complete(result); return; } - + if (data.getSize() == null && data.getType() == DataObjectType.TEMPLATE) { //the template size is unknown during registration, need to find out the size of template EndPoint ep = selector.select(data); @@ -92,14 +100,14 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd); if (answer.getResult()) { //update imagestorevo - + result = new CreateCmdResult(answer.getPath(), answer.getSize()); } else { result.setResult(answer.getDetails()); } - + } - + callback.complete(result); } @@ -120,13 +128,13 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 8504de9a15e..e96bfffa6a2 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -19,10 +19,12 @@ package org.apache.cloudstack.storage.datastore.driver; import java.util.List; +import java.util.Map; import java.util.Set; import javax.inject.Inject; +import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -34,7 +36,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -43,6 +47,7 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.host.HostVO; @@ -77,6 +82,8 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { @Inject DownloadMonitor _downloadMonitor; @Inject VMTemplateHostDao _vmTemplateHostDao; + @Inject + ImageStoreDetailsDao _imageStoreDetailsDao; @Inject VolumeDao volumeDao; @Inject VolumeHostDao volumeHostDao; @Inject HostDao hostDao; @@ -92,12 +99,22 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub return null; } - + @Override public DataTO getTO(DataObject data) { return null; } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + ImageStoreImpl imgStore = (ImageStoreImpl)store; + Map details = _imageStoreDetailsDao.getDetails(imgStore.getId()); + return new SwiftTO(imgStore.getId(), imgStore.getUri(), details.get(ApiConstants.ACCOUNT), + details.get(ApiConstants.USERNAME), + details.get(ApiConstants.KEY)); + } + @Override public boolean revokeAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 412647fb993..2a9217de6c4 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -46,6 +46,7 @@ import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; @@ -91,13 +92,20 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri // TODO Auto-generated method stub return null; } - + @Override public DataTO getTO(DataObject data) { return null; } + @Override + public DataStoreTO getStoreTO(DataStore store) { + // TODO Auto-generated method stub + return null; + } + + @Override public boolean revokeAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub return false; @@ -148,7 +156,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri + template.getId() + " " + template.getName()); throw new CloudRuntimeException("cannot find template" - + template.getId() + + template.getId() + template.getName()); } HostVO secondaryStorageHost = hostDao @@ -304,11 +312,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri parentSnapshotPath = preSnapshotVO.getPath(); } StoragePool srcPool = (StoragePool)volume.getDataStore(); - + ManageSnapshotCommand cmd = new ManageSnapshotCommand(snapshot.getId(), volume.getPath(), srcPool, parentSnapshotPath, snapshot.getName(), vmName); ManageSnapshotAnswer answer = (ManageSnapshotAnswer) this.snapshotMgr.sendToPool(volume, cmd); - + if ((answer != null) && answer.getResult()) { result = new CreateCmdResult(answer.getSnapshotPath(), null); } else { diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index 4308558bf0c..6875b7a5217 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -30,7 +30,6 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; @@ -61,6 +60,7 @@ import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; import com.cloud.storage.OCFS2Manager; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index 99b16ebd5df..fc62a563aba 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -41,6 +41,7 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; @@ -56,14 +57,22 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver @Inject DataObjectManager dataObjMgr; public SamplePrimaryDataStoreDriverImpl() { - + } - + @Override public DataTO getTO(DataObject data) { return null; } - + + + @Override + public DataStoreTO getStoreTO(DataStore store) { + // TODO Auto-generated method stub + return null; + } + + private class CreateVolumeContext extends AsyncRpcConext { private final DataObject volume; /** @@ -73,13 +82,13 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver super(callback); this.volume = volume; } - + public DataObject getVolume() { return this.volume; } - + } - + public Void createAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = null; CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); @@ -89,15 +98,15 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver result = new CreateCmdResult("", null); result.setResult(volAnswer.getDetails()); } - + context.getParentCallback().complete(result); return null; } - + @Override public void deleteAsync(DataObject vo, AsyncCompletionCallback callback) { DeleteCommand cmd = new DeleteCommand(vo.getUri()); - + EndPoint ep = selector.select(vo); AsyncRpcConext context = new AsyncRpcConext(callback); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); @@ -105,7 +114,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver .setContext(context); ep.sendMessageAsync(cmd, caller); } - + public Void deleteCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { CommandResult result = new CommandResult(); Answer answer = callback.getResult(); @@ -118,16 +127,16 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver /* private class CreateVolumeFromBaseImageContext extends AsyncRpcConext { private final VolumeObject volume; - + public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject volume) { super(callback); this.volume = volume; } - + public VolumeObject getVolume() { return this.volume; } - + } @Override @@ -137,7 +146,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver EndPoint ep = endPoints.get(0); String templateUri = template.getDataStore().grantAccess(template, ep); CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, templateUri); - + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(callback, volume); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context) @@ -169,7 +178,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver AsyncCompletionCallback callback) { EndPoint ep = selector.select(vol); CreateObjectCommand createCmd = new CreateObjectCommand(vol.getUri()); - + CreateVolumeContext context = new CreateVolumeContext(callback, vol); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context) @@ -181,7 +190,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver @Override public String grantAccess(DataObject object, EndPoint ep) { //StoragePoolHostVO poolHost = storeHostDao.findByPoolHost(object.getDataStore().getId(), ep.getId()); - + String uri = object.getUri(); try { DecodedDataObject obj = Decoder.decode(uri); @@ -197,7 +206,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver throw new CloudRuntimeException("failed to create object" + answer.getDetails()); } } - + return object.getUri(); } catch (URISyntaxException e) { throw new CloudRuntimeException("uri parsed error", e); @@ -220,10 +229,10 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } - + @Override public boolean canCopy(DataObject srcData, DataObject destData) { @@ -235,21 +244,21 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } - + } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 3916773c7f4..4ec0373316e 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -29,6 +29,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import com.cloud.agent.api.to.DataStoreTO; + public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Override @@ -36,12 +38,19 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { // TODO Auto-generated method stub return null; } - + @Override public DataTO getTO(DataObject data) { return null; } + + @Override + public DataStoreTO getStoreTO(DataStore store) { + // TODO Auto-generated method stub + return null; + } + @Override public boolean revokeAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -57,19 +66,19 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override @@ -81,21 +90,21 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Override public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { // TODO Auto-generated method stub - + } diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index ef567694733..1af3b2f54e6 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -51,7 +51,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.region.dao.RegionDao; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -114,6 +113,7 @@ import com.cloud.org.Grouping; import com.cloud.org.Grouping.AllocationState; import com.cloud.org.Managed; import com.cloud.service.ServiceOfferingVO; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.ImageStore; import com.cloud.storage.S3; diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 3b1a768f0fe..a5f82a8daef 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -53,7 +53,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; 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.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; diff --git a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java index 9bba979b9c0..40017756fd4 100644 --- a/server/src/com/cloud/storage/StoragePoolAutomationImpl.java +++ b/server/src/com/cloud/storage/StoragePoolAutomationImpl.java @@ -27,7 +27,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index ddd6ff00b83..4b870800355 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -45,7 +45,6 @@ import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; 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.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index bdac44d9a0d..7a1984cda4e 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -30,7 +30,6 @@ 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.log4j.Logger; import org.springframework.context.annotation.Primary; @@ -98,6 +97,7 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 06cf6ac7fed..cbffa8ee1ee 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -34,7 +34,6 @@ import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -54,6 +53,7 @@ import com.cloud.host.HostVO; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.TemplateProfile; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 1e79b60f150..05ba35d1c1a 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -28,7 +28,6 @@ import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; 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.DataStoreRole; import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; @@ -47,6 +46,7 @@ import com.cloud.org.Grouping; import com.cloud.storage.GuestOS; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.TemplateProfile; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index aabdaf9b22b..88a4e7f73f7 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -56,7 +56,6 @@ import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissions import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.DataStoreRole; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -121,6 +120,7 @@ import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; From 593337565e75f114075053dc06f51165bb862508 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 15 Apr 2013 14:44:39 -0700 Subject: [PATCH 025/303] Add S3 code to handle DownloadCommand for registerTemplate. --- .../agent/api/storage/DownloadCommand.java | 29 +++++- api/src/com/cloud/agent/api/to/NfsTO.java | 60 ++++++++++++ .../resource/NfsSecondaryStorageResource.java | 97 ++++++++++++++----- .../storage/template/DownloadManagerImpl.java | 40 +++++--- .../cloud/agent/transport/RequestTest.java | 18 ++-- .../motion/AncientDataMotionStrategy.java | 41 ++++---- .../storage/image/store/ImageStoreImpl.java | 2 +- .../datastore/PrimaryDataStoreImpl.java | 14 +-- .../CloudStackImageStoreDriverImpl.java | 6 +- .../storage/download/DownloadMonitorImpl.java | 2 +- utils/src/com/cloud/utils/S3Utils.java | 21 ++++ utils/src/com/cloud/utils/UriUtils.java | 81 ++++++++++++++++ 12 files changed, 336 insertions(+), 75 deletions(-) create mode 100644 api/src/com/cloud/agent/api/to/NfsTO.java diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/api/src/com/cloud/agent/api/storage/DownloadCommand.java index c6ffe45a9ef..77e7ae32b68 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadCommand.java @@ -20,6 +20,7 @@ import java.net.URI; import org.apache.cloudstack.api.InternalIdentity; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; @@ -105,6 +106,8 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal private Long maxDownloadSizeInBytes = null; private long id; private ResourceType resourceType = ResourceType.TEMPLATE; + private DataStoreTO _store; + private Long resourceId; protected DownloadCommand() { } @@ -122,14 +125,16 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal this.resourceType = that.resourceType; } - public DownloadCommand(String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { + public DownloadCommand(DataStoreTO store, String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { super(template.getUniqueName(), template.getUrl(), template.getFormat(), template.getAccountId()); + this._store = store; this.hvm = template.isRequiresHvm(); this.checksum = template.getChecksum(); this.id = template.getId(); this.description = template.getDisplayText(); this.setSecUrl(secUrl); this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + this.resourceId = template.getId(); } public DownloadCommand(String secUrl, Volume volume, Long maxDownloadSizeInBytes, String checkSum, String url, ImageFormat format) { @@ -216,4 +221,26 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } + + + public DataStoreTO getDataStore() { + return _store; + } + + + public void setDataStore(DataStoreTO _store) { + this._store = _store; + } + + + public Long getResourceId() { + return resourceId; + } + + + public void setResourceId(Long resourceId) { + this.resourceId = resourceId; + } + + } diff --git a/api/src/com/cloud/agent/api/to/NfsTO.java b/api/src/com/cloud/agent/api/to/NfsTO.java new file mode 100644 index 00000000000..5490fd1e588 --- /dev/null +++ b/api/src/com/cloud/agent/api/to/NfsTO.java @@ -0,0 +1,60 @@ +// 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.agent.api.to; + +import com.cloud.storage.DataStoreRole; + +public final class NfsTO implements DataStoreTO { + + private String _url; + private DataStoreRole _role; + + public NfsTO() { + + super(); + + } + + public NfsTO(String url, DataStoreRole role) { + + super(); + + this._url = url; + this._role = role; + + } + + public String getUrl() { + return _url; + } + + public void setUrl(String _url) { + this._url = _url; + } + + @Override + public DataStoreRole getRole() { + return _role; + } + + public void setRole(DataStoreRole _role) { + this._role = _role; + } + + + +} diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index a8788c66b64..776ce29ec6a 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -34,7 +34,10 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.net.InetAddress; +import java.net.MalformedURLException; import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -90,6 +93,8 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.ssCommand; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.exception.InternalErrorException; @@ -106,6 +111,7 @@ import com.cloud.storage.template.UploadManager; import com.cloud.storage.template.UploadManagerImpl; import com.cloud.utils.NumbersUtil; import com.cloud.utils.S3Utils; +import com.cloud.utils.UriUtils; import com.cloud.utils.S3Utils.FileNamingStrategy; import com.cloud.utils.S3Utils.ObjectNamingStrategy; import com.cloud.utils.component.ComponentContext; @@ -126,7 +132,7 @@ SecondaryStorageResource { int _timeout; - String _instance; + String _instance; String _dc; String _pod; String _guid; @@ -162,8 +168,8 @@ SecondaryStorageResource { if (cmd instanceof DownloadProgressCommand) { return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd); } else if (cmd instanceof DownloadCommand) { - return _dlMgr.handleDownloadCommand(this, (DownloadCommand)cmd); - } else if (cmd instanceof UploadCommand) { + return execute((DownloadCommand)cmd); + } else if (cmd instanceof UploadCommand) { return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd); } else if (cmd instanceof CreateEntityDownloadURLCommand){ return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd); @@ -325,6 +331,51 @@ SecondaryStorageResource { } } + private Answer execute(DownloadCommand cmd){ + DataStoreTO dstore = cmd.getDataStore(); + if ( dstore instanceof NfsTO ){ + return _dlMgr.handleDownloadCommand(this, cmd); + } + else if ( dstore instanceof S3TO ){ + //TODO: how to handle download progress for S3 + S3TO s3 = (S3TO)cmd.getDataStore(); + String url = cmd.getUrl(); + String user = null; + String password = null; + if (cmd.getAuth() != null) { + user = cmd.getAuth().getUserName(); + password = new String(cmd.getAuth().getPassword()); + } + // get input stream from the given url + InputStream in = UriUtils.getInputStreamFromUrl(url, user, password); + URI uri; + URL urlObj; + try { + uri = new URI(url); + urlObj = new URL(url); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("URI is incorrect: " + url); + } catch (MalformedURLException e) { + throw new CloudRuntimeException("URL is incorrect: " + url); + } + + final String bucket = s3.getBucketName(); + String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR); + S3Utils.putObject(s3, in, bucket, key); + return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url, + cmd.getResourceId(), bucket)); + } + else if ( dstore instanceof SwiftTO ){ + //TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle + // source is url, most likely we need to modify our existing swiftUpload python script. + return new Answer(cmd, false, "Swift is not currently support DownloadCommand"); + } + else{ + return new Answer(cmd, false, "Unsupport image data store: " + dstore); + } + + } + private Answer execute(uploadTemplateToSwiftFromSecondaryStorageCommand cmd) { SwiftTO swift = cmd.getSwift(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); @@ -834,33 +885,33 @@ SecondaryStorageResource { String absoluteTemplatePath = parent + relativeTemplatePath; MessageDigest digest; String checksum = null; - File f = new File(absoluteTemplatePath); + File f = new File(absoluteTemplatePath); InputStream is = null; byte[] buffer = new byte[8192]; int read = 0; if(s_logger.isDebugEnabled()){ - s_logger.debug("parent path " +parent+ " relative template path " +relativeTemplatePath ); + s_logger.debug("parent path " +parent+ " relative template path " +relativeTemplatePath ); } try { - digest = MessageDigest.getInstance("MD5"); - is = new FileInputStream(f); + digest = MessageDigest.getInstance("MD5"); + is = new FileInputStream(f); while( (read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); - } + } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); checksum = bigInt.toString(16); if(s_logger.isDebugEnabled()){ - s_logger.debug("Successfully calculated checksum for file " +absoluteTemplatePath+ " - " +checksum ); + s_logger.debug("Successfully calculated checksum for file " +absoluteTemplatePath+ " - " +checksum ); } }catch(IOException e) { String logMsg = "Unable to process file for MD5 - " + absoluteTemplatePath; s_logger.error(logMsg); - return new Answer(cmd, false, checksum); - }catch (NoSuchAlgorithmException e) { + return new Answer(cmd, false, checksum); + }catch (NoSuchAlgorithmException e) { return new Answer(cmd, false, checksum); } finally { @@ -869,10 +920,10 @@ SecondaryStorageResource { is.close(); } catch (IOException e) { if(s_logger.isDebugEnabled()){ - s_logger.debug("Could not close the file " +absoluteTemplatePath); + s_logger.debug("Could not close the file " +absoluteTemplatePath); } - return new Answer(cmd, false, checksum); - } + return new Answer(cmd, false, checksum); + } } return new Answer(cmd, true, checksum); @@ -1141,7 +1192,7 @@ SecondaryStorageResource { if (nfsIps.contains(cidr)) { /* * if the internal download ip is the same with secondary storage ip, adding internal sites will flush - * ip route to nfs through storage ip. + * ip route to nfs through storage ip. */ continue; } @@ -1243,7 +1294,7 @@ SecondaryStorageResource { for (PortConfig pCfg:cmd.getPortConfigs()){ if (pCfg.isAdd()) { - ipList.add(pCfg.getSourceIp()); + ipList.add(pCfg.getSourceIp()); } } boolean success = true; @@ -1401,7 +1452,7 @@ SecondaryStorageResource { String nfsPath = nfsHostIp + ":" + uri.getPath(); String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString(); String root = _parent + "/" + dir; - mount(root, nfsPath); + mount(root, nfsPath); return root; } catch (Exception e) { String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); @@ -1470,7 +1521,7 @@ SecondaryStorageResource { String eth2ip = (String) params.get("eth2ip"); if (eth2ip != null) { params.put("public.network.device", "eth2"); - } + } _publicIp = (String) params.get("eth2ip"); _hostname = (String) params.get("name"); @@ -1677,7 +1728,7 @@ SecondaryStorageResource { command.add(String.valueOf(isAppend)); for (String ip : ipList){ command.add(ip); - } + } String result = command.execute(); if (result != null) { @@ -1693,7 +1744,7 @@ SecondaryStorageResource { s_logger.debug("create mount point: " + root); } else { s_logger.debug("Unable to create mount point: " + root); - return null; + return null; } } @@ -1813,13 +1864,13 @@ SecondaryStorageResource { @Override public void setName(String name) { // TODO Auto-generated method stub - + } @Override public void setConfigParams(Map params) { // TODO Auto-generated method stub - + } @Override @@ -1837,6 +1888,6 @@ SecondaryStorageResource { @Override public void setRunLevel(int level) { // TODO Auto-generated method stub - + } } diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index db264c17bb1..7eb68418b42 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -16,9 +16,15 @@ // under the License. package com.cloud.storage.template; +import static com.cloud.utils.S3Utils.putDirectory; +import static com.cloud.utils.StringUtils.join; +import static java.lang.String.format; +import static java.util.Arrays.asList; + import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; +import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; @@ -41,14 +47,21 @@ import java.util.concurrent.Executors; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.log4j.Logger; +import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import com.cloud.agent.api.to.S3TO; import com.cloud.exception.InternalErrorException; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; @@ -59,6 +72,9 @@ import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback; import com.cloud.storage.template.TemplateDownloader.Status; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.S3Utils; +import com.cloud.utils.UriUtils; +import com.cloud.utils.S3Utils.ObjectNamingStrategy; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.OutputInterpreter; @@ -224,7 +240,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager /** * Get notified of change of job status. Executed in context of downloader thread - * + * * @param jobId * the id of the job * @param status @@ -279,21 +295,21 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager byte[] buffer = new byte[8192]; int read = 0; MessageDigest digest; - String checksum = null; + String checksum = null; InputStream is = null; try { - digest = MessageDigest.getInstance("MD5"); - is = new FileInputStream(f); + digest = MessageDigest.getInstance("MD5"); + is = new FileInputStream(f); while( (read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); - } + } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); checksum = String.format("%032x",bigInt); return checksum; }catch(IOException e) { return null; - }catch (NoSuchAlgorithmException e) { + }catch (NoSuchAlgorithmException e) { return null; } finally { @@ -302,19 +318,19 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager is.close(); } catch (IOException e) { return null; - } + } } } /** * Post download activity (install and cleanup). Executed in context of downloader thread - * + * * @throws IOException */ private String postDownload(String jobId) { DownloadJob dnld = jobs.get(jobId); TemplateDownloader td = dnld.getTemplateDownloader(); - String resourcePath = null; + String resourcePath = null; ResourceType resourceType = dnld.getResourceType(); // once template path is set, remove the parent dir so that the template is installed with a relative path @@ -458,7 +474,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return "Unable to create " + tmpDir; } // TO DO - define constant for volume properties. - File file = ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : + File file = ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage.getFile(tmpDir + File.separator + "volume.properties"); if ( file.exists() ) { file.delete(); @@ -583,6 +599,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return convertStatus(getDownloadStatus(jobId)); } + @Override public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) { ResourceType resourceType = cmd.getResourceType(); @@ -774,7 +791,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } @Override - public Map gatherVolumeInfo(String rootDir) { + public Map gatherVolumeInfo(String rootDir) { Map result = new HashMap(); String volumeDir = rootDir + File.separator + _volumeDir; @@ -1046,4 +1063,5 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } } + } diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 64c1e0bddef..048bd21db7c 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -31,19 +31,21 @@ import com.cloud.agent.api.SecStorageFirewallCfgCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; +import com.cloud.agent.api.to.NfsTO; import com.cloud.exception.UnsupportedVersionException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.serializer.GsonHelper; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateVO; /** - * - * - * - * + * + * + * + * */ public class RequestTest extends TestCase { @@ -51,7 +53,7 @@ public class RequestTest extends TestCase { public void testSerDeser() { s_logger.info("Testing serializing and deserializing works as expected"); - + s_logger.info("UpdateHostPasswordCommand should have two parameters that doesn't show in logging"); UpdateHostPasswordCommand cmd1 = new UpdateHostPasswordCommand("abc", "def"); s_logger.info("SecStorageFirewallCfgCommand has a context map that shouldn't show up in debug level"); @@ -89,7 +91,7 @@ public class RequestTest extends TestCase { logger.setLevel(level); byte[] bytes = sreq.getBytes(); - + assert Request.getSequence(bytes) == 892403717; assert Request.getManagementServerId(bytes) == 3; assert Request.getAgentId(bytes) == 2; @@ -130,7 +132,7 @@ public class RequestTest extends TestCase { s_logger.info("Testing Download answer"); VMTemplateVO template = new VMTemplateVO(1, "templatename", ImageFormat.QCOW2, true, true, true, TemplateType.USER, "url", true, 32, 1, "chksum", "displayText", true, 30, true, HypervisorType.KVM, null); - DownloadCommand cmd = new DownloadCommand("secUrl", template, 30000000l); + DownloadCommand cmd = new DownloadCommand(new NfsTO("secUrl", DataStoreRole.Image), "secUrl", template, 30000000l); Request req = new Request(1, 1, cmd, true); req.logD("Debug for Download"); @@ -161,7 +163,7 @@ public class RequestTest extends TestCase { } } } - + public void testLogging() { s_logger.info("Testing Logging"); GetHostStatsCommand cmd3 = new GetHostStatsCommand("hostguid", "hostname", 101); 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 index efc2f99973b..e72bb54ddec 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -28,7 +28,7 @@ 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.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -65,6 +65,7 @@ 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.DataStoreRole; import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; @@ -130,7 +131,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { VolumeManager volumeMgr; @Inject private SwiftManager _swiftMgr; - @Inject + @Inject private S3Manager _s3Mgr; @Inject StorageCacheManager cacheMgr; @@ -314,12 +315,12 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } } } - + 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, @@ -334,7 +335,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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; @@ -345,7 +346,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { vol.setPoolId(pool.getId()); vol.setPodId(pool.getPodId()); this.volDao.update(vol.getId(), vol); - + } else { if (tmpltStoredOn != null && (answer instanceof CreateAnswer) @@ -354,15 +355,15 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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; @@ -370,9 +371,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { .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())); @@ -394,7 +395,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } String secondaryStorageVolumePath = cvAnswer.getVolumePath(); - + cvCmd = new CopyVolumeCommand(volume.getId(), secondaryStorageVolumePath, destPool, secondaryStorageURL, false, _copyvolumewait); @@ -409,7 +410,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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); @@ -437,7 +438,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } else if (srcData.getType() == DataObjectType.VOLUME && destData.getType() == DataObjectType.TEMPLATE) { answer = createTemplateFromVolume(srcData, destData); - } else if (srcData.getType() == DataObjectType.TEMPLATE + } else if (srcData.getType() == DataObjectType.TEMPLATE && destData.getType() == DataObjectType.VOLUME) { answer = cloneVolume(srcData, destData); } else if (destData.getType() == DataObjectType.VOLUME @@ -667,21 +668,21 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return sendCommand(cmd, pool, template.getId(), zoneId, secondaryStorageHost.getId()); } - + private HostVO getSecHost(long volumeId, long dcId) { Long id = snapshotDao.getSecHostId(volumeId); - if ( id != null) { + 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(); @@ -696,12 +697,12 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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")) { + if (prevSnapshot.getVersion() != null && prevSnapshot.getVersion().equals("2.2")) { prevBackupUuid = prevSnapshot.getBackupSnapshotId(); prevSnapshotUuid = prevSnapshot.getPath(); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 4989b2629a2..bc8d2e2a10f 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -175,7 +175,7 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public DataStoreTO getTO() { - return null; + return getDriver().getStoreTO(this); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 0feefd0528c..8be1c8a7e47 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -83,10 +83,10 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { private VolumeDao volumeDao; - public PrimaryDataStoreImpl() { - + public PrimaryDataStoreImpl() { + } - + public void configure(StoragePoolVO pdsv, PrimaryDataStoreDriver driver, DataStoreProvider provider) { this.pdsv = pdsv; @@ -245,9 +245,9 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { } } } - + } - + return objectInStoreMgr.get(obj, this); } @@ -341,9 +341,9 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { public String getStorageProviderName() { return this.pdsv.getStorageProviderName(); } - + @Override public DataStoreTO getTO() { - return null; + return getDriver().getStoreTO(this); } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index af6a3b63492..f90238571dc 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -46,6 +46,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.host.HostVO; @@ -106,10 +107,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { @Override public DataStoreTO getStoreTO(DataStore store) { ImageStoreImpl nfsStore = (ImageStoreImpl)store; - ImageStoreTO nfsTO = new ImageStoreTO(); - nfsTO.setProviderName("CloudStack"); + NfsTO nfsTO = new NfsTO(); nfsTO.setRole(DataStoreRole.Image); - nfsTO.setUri(nfsStore.getUri()); + nfsTO.setUrl(nfsStore.getUri()); return nfsTO; } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 507d57531fe..58477b43e90 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -366,7 +366,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if(vmTemplateStore != null) { start(); DownloadCommand dcmd = - new DownloadCommand(secUrl, template, maxTemplateSizeInBytes); + new DownloadCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index b7273a14869..423ea7138a9 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -138,6 +138,24 @@ public final class S3Utils { } + public static void putObject(final ClientOptions clientOptions, + final InputStream sourceStream, final String bucketName, final String key) { + + assert clientOptions != null; + assert sourceStream != null; + assert !isBlank(bucketName); + assert !isBlank(key); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(format("Sending stream as S3 object %1$s in " + + "bucket %2$s", key, bucketName)); + } + + acquireClient(clientOptions).putObject(bucketName, key, sourceStream, null); + + } + + @SuppressWarnings("unchecked") public static File getFile(final ClientOptions clientOptions, final String bucketName, final String key, @@ -239,6 +257,7 @@ public final class S3Utils { } + public static void putDirectory(final ClientOptions clientOptions, final String bucketName, final File directory, final FilenameFilter fileNameFilter, @@ -284,6 +303,8 @@ public final class S3Utils { } + + public static void deleteObject(final ClientOptions clientOptions, final String bucketName, final String key) { diff --git a/utils/src/com/cloud/utils/UriUtils.java b/utils/src/com/cloud/utils/UriUtils.java index 3bcee7aeac4..ef1aba24a00 100644 --- a/utils/src/com/cloud/utils/UriUtils.java +++ b/utils/src/com/cloud/utils/UriUtils.java @@ -18,16 +18,34 @@ package com.cloud.utils; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.net.HttpURLConnection; +import java.net.Inet6Address; +import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.net.UnknownHostException; import javax.net.ssl.HttpsURLConnection; +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.log4j.Logger; + import com.cloud.utils.exception.CloudRuntimeException; public class UriUtils { + + public static final Logger s_logger = Logger.getLogger(UriUtils.class.getName()); + public static String formNfsUri(String host, String path) { try { URI uri = new URI("nfs", host, path, null); @@ -111,4 +129,67 @@ public class UriUtils { } return remoteSize; } + + public static Pair validateUrl(String url) throws IllegalArgumentException { + try { + URI uri = new URI(url); + if (!uri.getScheme().equalsIgnoreCase("http") && !uri.getScheme().equalsIgnoreCase("https") ) { + throw new IllegalArgumentException("Unsupported scheme for url"); + } + int port = uri.getPort(); + if (!(port == 80 || port == 443 || port == -1)) { + throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); + } + + if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { + port = 443; + } else if (port == -1 && uri.getScheme().equalsIgnoreCase("http")) { + port = 80; + } + + String host = uri.getHost(); + try { + InetAddress hostAddr = InetAddress.getByName(host); + if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { + throw new IllegalArgumentException("Illegal host specified in url"); + } + if (hostAddr instanceof Inet6Address) { + throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); + } + return new Pair(host, port); + } catch (UnknownHostException uhe) { + throw new IllegalArgumentException("Unable to resolve " + host); + } + } catch (URISyntaxException use) { + throw new IllegalArgumentException("Invalid URL: " + url); + } + } + + public static InputStream getInputStreamFromUrl(String url, String user, String password) { + + try{ + Pair hostAndPort = validateUrl(url); + HttpClient httpclient = new HttpClient(new MultiThreadedHttpConnectionManager()); + if ((user != null) && (password != null)) { + httpclient.getParams().setAuthenticationPreemptive(true); + Credentials defaultcreds = new UsernamePasswordCredentials(user, password); + httpclient.getState().setCredentials(new AuthScope(hostAndPort.first(), hostAndPort.second(), AuthScope.ANY_REALM), defaultcreds); + s_logger.info("Added username=" + user + ", password=" + password + "for host " + hostAndPort.first() + ":" + hostAndPort.second()); + } + // Execute the method. + GetMethod method = new GetMethod(url); + int statusCode = httpclient.executeMethod(method); + + if (statusCode != HttpStatus.SC_OK) { + s_logger.error("Failed to read from URL: " + url); + return null; + } + + return method.getResponseBodyAsStream(); + } + catch (Exception ex){ + s_logger.error("Failed to read from URL: " + url); + return null; + } + } } From 0da2da852b7615b19ab2b35ec9985389acacca65 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 16 Apr 2013 12:03:12 -0700 Subject: [PATCH 026/303] Fix the flow of deleteTemplateCmd. --- .../api/storage/DeleteTemplateCommand.java | 25 +- core/src/com/cloud/storage/VMTemplateVO.java | 32 +- .../resource/NfsSecondaryStorageResource.java | 138 +++++-- .../datastore/db/TemplateDataStoreDao.java | 8 + .../storage/image/ImageDataFactoryImpl.java | 14 +- .../storage/image/TemplateServiceImpl.java | 50 ++- .../storage/image/store/TemplateObject.java | 13 +- .../image/db/TemplateDataStoreDaoImpl.java | 53 ++- .../CloudStackImageStoreDriverImpl.java | 76 ++++ .../com/cloud/storage/StorageManagerImpl.java | 67 ++-- .../template/HypervisorTemplateAdapter.java | 160 +++----- .../cloud/template/TemplateAdapterBase.java | 2 + .../com/cloud/template/TemplateManager.java | 15 +- .../cloud/template/TemplateManagerImpl.java | 346 +++++++++++------- setup/db/db/schema-410to420.sql | 2 +- 15 files changed, 637 insertions(+), 364 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java b/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java index 69f465c6b16..9b874cf5156 100644 --- a/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java @@ -16,17 +16,26 @@ // under the License. package com.cloud.agent.api.storage; +import com.cloud.agent.api.to.DataStoreTO; + public class DeleteTemplateCommand extends ssCommand { + private DataStoreTO store; private String templatePath; + private Long templateId; + private Long accountId; public DeleteTemplateCommand() { } - public DeleteTemplateCommand(String secUrl, String templatePath) { + + public DeleteTemplateCommand(DataStoreTO store, String secUrl, String templatePath, Long templateId, Long accountId) { this.setSecUrl(secUrl); this.templatePath = templatePath; + this.templateId = templateId; + this.accountId = accountId; + this.store = store; } @Override @@ -37,4 +46,18 @@ public class DeleteTemplateCommand extends ssCommand { public String getTemplatePath() { return templatePath; } + + public Long getTemplateId() { + return templateId; + } + + public Long getAccountId() { + return accountId; + } + + public DataStoreTO getDataStore() { + return store; + } + + } diff --git a/core/src/com/cloud/storage/VMTemplateVO.java b/core/src/com/cloud/storage/VMTemplateVO.java index e643d75bf1e..e3339fdd6b4 100755 --- a/core/src/com/cloud/storage/VMTemplateVO.java +++ b/core/src/com/cloud/storage/VMTemplateVO.java @@ -128,19 +128,16 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject listByStoreId(long id); + public List listDestroyed(long storeId); + public void deletePrimaryRecordsForStore(long id); + List listByTemplateStore(long templateId, long storeId); + List listByTemplateStoreStatus(long templateId, long storeId, State... states); List listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status); TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId); + + TemplateDataStoreVO findByTemplate(long templateId); + + List listByTemplate(long templateId); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java index 37204bf0386..d2c2520c74e 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java @@ -28,6 +28,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -50,6 +52,8 @@ public class ImageDataFactoryImpl implements ImageDataFactory { DataStoreManager storeMgr; @Inject VMTemplatePoolDao templatePoolDao; + @Inject + TemplateDataStoreDao templateStoreDao; @Override public TemplateInfo getTemplate(long templateId, DataStore store) { VMTemplateVO templ = imageDataDao.findById(templateId); @@ -77,13 +81,17 @@ public class ImageDataFactoryImpl implements ImageDataFactory { TemplateObject tmpl = TemplateObject.getTemplate(templ, store); return tmpl; } + + //TODO: this method is problematic, since one template can be stored in multiple image stores. + // need to see if we can get rid of this method or change to plural format. @Override public TemplateInfo getTemplate(long templateId) { VMTemplateVO templ = imageDataDao.findById(templateId); - if (templ.getImageDataStoreId() == null) { - return this.getTemplate(templateId, null); + TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId); + DataStore store = null; + if ( tmplStore != null ){ + store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), DataStoreRole.Image); } - DataStore store = this.storeMgr.getDataStore(templ.getImageDataStoreId(), DataStoreRole.Image); return this.getTemplate(templateId, store); } @Override diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 3dcb86b0939..38381082216 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -40,6 +40,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import com.cloud.storage.template.TemplateProp; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -139,6 +141,28 @@ public class TemplateServiceImpl implements TemplateService { } } + class DeleteTemplateContext extends AsyncRpcConext { + final TemplateObject template; + final AsyncCallFuture future; + + public DeleteTemplateContext(AsyncCompletionCallback callback, TemplateObject template, + AsyncCallFuture future) { + super(callback); + this.template = template; + this.future = future; + } + + public TemplateObject getTemplate() { + return template; + } + + public AsyncCallFuture getFuture() { + return future; + } + + + } + @Override public AsyncCallFuture createTemplateAsync( TemplateInfo template, DataStore store) { @@ -361,7 +385,8 @@ public class TemplateServiceImpl implements TemplateService { List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getUri(), tInfo.getInstallPath()); + VMTemplateVO template = _templateDao.findById(tInfo.getId()); + DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), store.getUri(), tInfo.getInstallPath(), template.getId(), template.getAccountId()); try { HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); @@ -458,7 +483,28 @@ public class TemplateServiceImpl implements TemplateService { @Override public AsyncCallFuture deleteTemplateAsync( TemplateInfo template) { - // TODO Auto-generated method stub + TemplateObject to = (TemplateObject) template; + // update template_store_ref status + to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + AsyncCallFuture future = new AsyncCallFuture(); + + DeleteTemplateContext context = new DeleteTemplateContext(null, to, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().deleteTemplateCallback(null, null)).setContext(context); + to.getDataStore().getDriver().deleteAsync(to, caller); + return future; + } + + public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, DeleteTemplateContext context) { + CommandResult result = callback.getResult(); + TemplateObject vo = context.getTemplate(); + // we can only update state in template_store_ref table + if (result.isSuccess()) { + vo.processEvent(Event.OperationSuccessed); + } else { + vo.processEvent(Event.OperationFailed); + } + context.getFuture().complete(result); return null; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 7727f12d91e..15aad4ba3e7 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -69,9 +69,6 @@ public class TemplateObject implements TemplateInfo { return to; } - public void setImageStoreId(long id) { - this.imageVO.setImageDataStoreId(id); - } public void setSize(Long size) { this.imageVO.setSize(size); @@ -85,7 +82,7 @@ public class TemplateObject implements TemplateInfo { public DataStore getDataStore() { return this.dataStore; } - + @Override public String getUniqueName() { return this.imageVO.getUniqueName(); @@ -126,7 +123,7 @@ public class TemplateObject implements TemplateInfo { if (templateHostVO == null) { VMTemplateSwiftVO templateSwiftVO = _swiftMgr.findByTmpltId(templateForVmCreation.getId()); - if (templateSwiftVO != null) { + if (templateSwiftVO != null) { long templateSize = templateSwiftVO.getPhysicalSize(); if (templateSize == 0) { templateSize = templateSwiftVO.getSize(); @@ -172,7 +169,7 @@ public class TemplateObject implements TemplateInfo { throw new CloudRuntimeException("Failed to update state" + e.toString()); } } - + @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { @@ -182,14 +179,14 @@ public class TemplateObject implements TemplateInfo { throw new CloudRuntimeException("Failed to update state" + e.toString()); } } - + @Override public DataTO getTO() { DataTO to = this.dataStore.getDriver().getTO(this); if (to == null) { to = new TemplateObjectTO(this); } - + return to; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index e34a1aba885..dd8e319323f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -43,9 +43,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; + private SearchBuilder templateSearch; + private SearchBuilder storeTemplateSearch; private SearchBuilder storeTemplateStateSearch; private SearchBuilder storeTemplateDownloadStatusSearch; - private SearchBuilder storeTemplateSearch; + @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -57,12 +59,24 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listDestroyed(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", true); + return listIncludingRemovedBy(sc); + } + @Override public void deletePrimaryRecordsForStore(long id) { SearchCriteria sc = storeSearch.create(); @@ -144,12 +166,22 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listByTemplateStore(long templateId, long storeId) { + SearchCriteria sc = storeTemplateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("store_id", storeId); + sc.setParameters("destroyed", false); + return search(sc, null); + } + @Override public List listByTemplateStoreStatus(long templateId, long storeId, State... states) { SearchCriteria sc = storeTemplateStateSearch.create(); sc.setParameters("template_id", templateId); sc.setParameters("store_id", storeId); sc.setParameters("states", (Object[])states); + sc.setParameters("destroyed", false); return search(sc, null); } @@ -157,10 +189,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) { - SearchCriteria sc = storeTemplateStateSearch.create(); + SearchCriteria sc = storeTemplateDownloadStatusSearch.create(); sc.setParameters("template_id", templateId); sc.setParameters("store_id", storeId); sc.setParameters("downloadState", (Object[])status); + sc.setParameters("destroyed", false); return search(sc, null); } @@ -173,6 +206,22 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = templateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + + @Override + public List listByTemplate(long templateId) { + SearchCriteria sc = templateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return search(sc, null); + } + } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index f90238571dc..85ebd230071 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -34,6 +34,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -44,17 +46,23 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.configuration.Resource.ResourceType; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.SnapshotVO; +import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; @@ -68,9 +76,14 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { private static final Logger s_logger = Logger @@ -92,6 +105,15 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject AccountDao _accountDao; + @Inject UserVmDao _userVmDao; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + private AgentManager _agentMgr; + @Inject TemplateDataStoreDao _templateStoreDao; + + @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -189,6 +211,60 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + TemplateObject templateObj = (TemplateObject) data; + VMTemplateVO template = templateObj.getImage(); + ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); + long storeId = store.getId(); + Long sZoneId = store.getDataCenterId(); + long templateId = template.getId(); + + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + String eventType = ""; + + if (template.getFormat().equals(ImageFormat.ISO)) { + eventType = EventTypes.EVENT_ISO_DELETE; + } else { + eventType = EventTypes.EVENT_TEMPLATE_DELETE; + } + + // TODO: need to understand why we need to mark destroyed in + // template_store_ref table here instead of in callback. + // Currently I did that in callback, so I removed previous code to mark template_host_ref + + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + // check if there is any VM using this ISO. + if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + Answer answer = _agentMgr.sendToSecStorage(ssAhost, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); + + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSucess(false); + callback.complete(result); + } + + VMTemplateZoneVO templateZone = templateZoneDao.findByZoneTemplate(sZoneId, templateId); + + if (templateZone != null) { + templateZoneDao.remove(templateZone.getId()); + } + } + } + } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index a5f82a8daef..cd15167f3fe 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1234,69 +1234,80 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C public void cleanupSecondaryStorage(boolean recurring) { try { // Cleanup templates in secondary storage hosts - List secondaryStorageHosts = _ssvmMgr - .listSecondaryStorageHostsInAllZones(); - for (HostVO secondaryStorageHost : secondaryStorageHosts) { + List imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(null)); + for (DataStore store : imageStores) { try { - long hostId = secondaryStorageHost.getId(); - List destroyedTemplateHostVOs = _vmTemplateHostDao - .listDestroyed(hostId); + long storeId = store.getId(); + List destroyedTemplateStoreVOs = this._templateStoreDao.listDestroyed(storeId); s_logger.debug("Secondary storage garbage collector found " - + destroyedTemplateHostVOs.size() + + destroyedTemplateStoreVOs.size() + " templates to cleanup on secondary storage host: " - + secondaryStorageHost.getName()); - for (VMTemplateHostVO destroyedTemplateHostVO : destroyedTemplateHostVOs) { + + store.getName()); + for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) { if (!_tmpltMgr - .templateIsDeleteable(destroyedTemplateHostVO)) { + .templateIsDeleteable(destroyedTemplateStoreVO)) { if (s_logger.isDebugEnabled()) { s_logger.debug("Not deleting template at: " - + destroyedTemplateHostVO); + + destroyedTemplateStoreVO); } continue; } if (s_logger.isDebugEnabled()) { - s_logger.debug("Deleting template host: " - + destroyedTemplateHostVO); + s_logger.debug("Deleting template store: " + + destroyedTemplateStoreVO); } - String installPath = destroyedTemplateHostVO + VMTemplateVO destroyedTemplate = this._vmTemplateDao.findById(destroyedTemplateStoreVO.getTemplateId()); + if ( destroyedTemplate == null ){ + s_logger.error("Cannot find template : " + destroyedTemplateStoreVO.getTemplateId() + " from template table"); + throw new CloudRuntimeException("Template " + destroyedTemplateStoreVO.getTemplateId() + " is found in secondary storage, but not found in template table"); + } + String installPath = destroyedTemplateStoreVO .getInstallPath(); + HostVO ssAhost = this._ssvmMgr.pickSsvmHost(store); if (installPath != null) { + Answer answer = _agentMgr.sendToSecStorage( - secondaryStorageHost, + ssAhost, new DeleteTemplateCommand( - secondaryStorageHost - .getStorageUrl(), - destroyedTemplateHostVO - .getInstallPath())); + store.getTO(), + store.getUri(), + destroyedTemplateStoreVO + .getInstallPath(), + destroyedTemplate.getId(), + destroyedTemplate.getAccountId() + + )); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " - + destroyedTemplateHostVO + + destroyedTemplateStoreVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails())); } else { _vmTemplateHostDao - .remove(destroyedTemplateHostVO.getId()); + .remove(destroyedTemplateStoreVO.getId()); s_logger.debug("Deleted template at: " - + destroyedTemplateHostVO + + destroyedTemplateStoreVO .getInstallPath()); } } else { - _vmTemplateHostDao.remove(destroyedTemplateHostVO + _vmTemplateHostDao.remove(destroyedTemplateStoreVO .getId()); } } } catch (Exception e) { s_logger.warn( - "problem cleaning up templates in secondary storage " - + secondaryStorageHost, e); + "problem cleaning up templates in secondary storage store " + + store.getName(), e); } } + List secondaryStorageHosts = _ssvmMgr + .listSecondaryStorageHostsInAllZones(); // Cleanup snapshot in secondary storage hosts for (HostVO secondaryStorageHost : secondaryStorageHosts) { try { @@ -2037,16 +2048,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (scope != null) { try { scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); - + } catch (Exception e) { throw new InvalidParameterValueException("invalid scope" + scope); } - + if (scopeType != ScopeType.ZONE) { throw new InvalidParameterValueException("Only zone wide cache storage is supported"); } } - + if (scopeType == ScopeType.ZONE && dcId == null) { throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index cbffa8ee1ee..3399ca1e92d 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -38,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -180,7 +181,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te } for (DataStore imageStore : imageStores) { AsyncCallFuture future = this.imageService - .createTemplateAsync(this.imageFactory.getTemplate(template.getId()), imageStore); + .createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore); try { future.get(); } catch (InterruptedException e) { @@ -202,123 +203,60 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te boolean success = true; VMTemplateVO template = (VMTemplateVO)profile.getTemplate(); - Long zoneId = profile.getZoneId(); - Long templateId = template.getId(); - String zoneName; - List secondaryStorageHosts; - if (!template.isCrossZones() && zoneId != null) { - DataCenterVO zone = _dcDao.findById(zoneId); - zoneName = zone.getName(); - secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId); - } else { - zoneName = "(all zones)"; - secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInAllZones(); - } + // find all eligible image stores for this template + List imageStores = this.templateMgr.getImageStoreByTemplate(template.getId(), profile.getZoneId()); + if ( imageStores == null || imageStores.size() == 0 ){ + throw new CloudRuntimeException("Unable to find image store to delete template "+ profile.getTemplate()); + } - s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName); + // Make sure the template is downloaded to all found image stores + for (DataStore store : imageStores) { + long storeId = store.getId(); + List templateStores = _tmpltStoreDao.listByTemplateStore(template.getId(), storeId); + for (TemplateDataStoreVO templateStore : templateStores) { + if (templateStore.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) { + String errorMsg = "Please specify a template that is not currently being downloaded."; + s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + store.getName() + "; cant' delete it."); + throw new CloudRuntimeException(errorMsg); + } + } + } - // Make sure the template is downloaded to all the necessary secondary storage hosts - for (HostVO secondaryStorageHost : secondaryStorageHosts) { - long hostId = secondaryStorageHost.getId(); - List templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId); - for (VMTemplateHostVO templateHostVO : templateHostVOs) { - if (templateHostVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) { - String errorMsg = "Please specify a template that is not currently being downloaded."; - s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + secondaryStorageHost.getName() + "; cant' delete it."); - throw new CloudRuntimeException(errorMsg); - } - } - } - Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); - String eventType = ""; + for (DataStore imageStore : imageStores) { + s_logger.info("Delete template from image store: " + imageStore.getName()); + AsyncCallFuture future = this.imageService + .deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore)); + try { + CommandResult result = future.get(); + success = result.isSuccess(); + if ( !success ) + break; + } catch (InterruptedException e) { + s_logger.debug("delete template Failed", e); + throw new CloudRuntimeException("delete template Failed", e); + } catch (ExecutionException e) { + s_logger.debug("delete template Failed", e); + throw new CloudRuntimeException("delete template Failed", e); + } + } - if (template.getFormat().equals(ImageFormat.ISO)){ - eventType = EventTypes.EVENT_ISO_DELETE; - } else { - eventType = EventTypes.EVENT_TEMPLATE_DELETE; - } + if (success) { + s_logger.info("Delete template from template table"); + // remove template from vm_templates table + if (_tmpltDao.remove(template.getId())) { + // Decrement the number of templates and total secondary storage + // space used by the account + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + _resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template); + _resourceLimitMgr.recalculateResourceCount(template.getAccountId(), account.getDomainId(), + ResourceType.secondary_storage.getOrdinal()); + } + } + return success; - // Iterate through all necessary secondary storage hosts and mark the template on each host as destroyed - for (HostVO secondaryStorageHost : secondaryStorageHosts) { - long hostId = secondaryStorageHost.getId(); - long sZoneId = secondaryStorageHost.getDataCenterId(); - List templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId); - for (VMTemplateHostVO templateHostVO : templateHostVOs) { - VMTemplateHostVO lock = _tmpltHostDao.acquireInLockTable(templateHostVO.getId()); - try { - if (lock == null) { - s_logger.debug("Failed to acquire lock when deleting templateHostVO with ID: " + templateHostVO.getId()); - success = false; - break; - } - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - templateHostVO.setDestroyed(true); - _tmpltHostDao.update(templateHostVO.getId(), templateHostVO); - String installPath = templateHostVO.getInstallPath(); - List userVmUsingIso = _userVmDao.listByIsoId(templateId); - //check if there is any VM using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage(secondaryStorageHost, new DeleteTemplateCommand(secondaryStorageHost.getStorageUrl(), installPath)); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " + templateHostVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails())); - } else { - _tmpltHostDao.remove(templateHostVO.getId()); - s_logger.debug("Deleted template at: " + installPath); - } - } else { - _tmpltHostDao.remove(templateHostVO.getId()); - } - } - VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(sZoneId, templateId); - - if (templateZone != null) { - _tmpltZoneDao.remove(templateZone.getId()); - } - } finally { - if (lock != null) { - _tmpltHostDao.releaseFromLockTable(lock.getId()); - } - } - } - - if (!success) { - break; - } - } - - s_logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName); - - // If there are no more non-destroyed template host entries for this template, delete it - if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) { - long accountId = template.getAccountId(); - - VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId); - - try { - if (lock == null) { - s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId); - success = false; - } else if (_tmpltDao.remove(templateId)) { - // Decrement the number of templates and total secondary storage space used by the account - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); - _resourceLimitMgr.recalculateResourceCount(accountId, account.getDomainId(), - ResourceType.secondary_storage.getOrdinal()); - } - - } finally { - if (lock != null) { - _tmpltDao.releaseFromLockTable(lock.getId()); - } - } - - s_logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed."); - } - - return success; } public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 05ba35d1c1a..987e6ed6ab5 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -28,6 +28,7 @@ import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.log4j.Logger; import com.cloud.api.ApiDBUtils; @@ -75,6 +76,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat protected @Inject DataCenterDao _dcDao; protected @Inject VMTemplateDao _tmpltDao; protected @Inject VMTemplateHostDao _tmpltHostDao; + protected @Inject TemplateDataStoreDao _tmpltStoreDao; protected @Inject VMTemplateZoneDao _tmpltZoneDao; protected @Inject UsageEventDao _usageEventDao; protected @Inject HostDao _hostDao; diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index af5488076e6..a5d94824e30 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -20,6 +20,7 @@ import java.util.List; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import com.cloud.dc.DataCenterVO; import com.cloud.exception.InternalErrorException; @@ -39,7 +40,7 @@ public interface TemplateManager extends TemplateApiService{ /** * Prepares a template for vm creation for a certain storage pool. - * + * * @param template * template to prepare * @param pool @@ -52,7 +53,7 @@ public interface TemplateManager extends TemplateApiService{ /** * Copies a template from its current secondary storage server to the secondary storage server in the specified zone. - * + * * @param template * @param srcSecHost * @param srcZone @@ -66,7 +67,7 @@ public interface TemplateManager extends TemplateApiService{ /** * Deletes a template from secondary storage servers - * + * * @param userId * @param templateId * @param zoneId @@ -77,7 +78,7 @@ public interface TemplateManager extends TemplateApiService{ /** * Lists templates in the specified storage pool that are not being used by any VM. - * + * * @param pool * @return list of VMTemplateStoragePoolVO */ @@ -85,13 +86,15 @@ public interface TemplateManager extends TemplateApiService{ /** * Deletes a template in the specified storage pool. - * + * * @param templatePoolVO */ void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO); boolean templateIsDeleteable(VMTemplateHostVO templateHostRef); + boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef); + VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool); @@ -117,4 +120,6 @@ public interface TemplateManager extends TemplateApiService{ String getChecksum(Long hostId, String templatePath); + List getImageStoreByTemplate(long templateId, Long zoneId); + } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 88a4e7f73f7..a4eb35c9620 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -65,8 +65,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -192,6 +196,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); @Inject VMTemplateDao _tmpltDao; @Inject VMTemplateHostDao _tmpltHostDao; + @Inject TemplateDataStoreDao _tmplStoreDao; @Inject VMTemplatePoolDao _tmpltPoolDao; @Inject VMTemplateZoneDao _tmpltZoneDao; @Inject @@ -253,21 +258,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, protected ResourceManager _resourceMgr; @Inject VolumeManager volumeMgr; @Inject VMTemplateHostDao templateHostDao; + @Inject ImageStoreDao _imageStoreDao; + - int _primaryStorageDownloadWait; protected SearchBuilder HostTemplateStatesSearch; - + int _storagePoolMaxWaitSeconds = 3600; boolean _disableExtraction = false; ExecutorService _preloadExecutor; ScheduledExecutorService _swiftTemplateSyncExecutor; - + private ScheduledExecutorService _s3TemplateSyncExecutor = null; @Inject protected List _adapters; - + private TemplateAdapter getAdapter(HypervisorType type) { TemplateAdapter adapter = null; if (type == HypervisorType.BareMetal) { @@ -276,21 +282,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // see HyervisorTemplateAdapter adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName()); } - + if (adapter == null) { throw new CloudRuntimeException("Cannot find template adapter for " + type.toString()); } - + return adapter; } - + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso") public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException{ TemplateAdapter adapter = getAdapter(HypervisorType.None); - TemplateProfile profile = adapter.prepare(cmd); + TemplateProfile profile = adapter.prepare(cmd); VMTemplateVO template = adapter.create(profile); - + if (template != null){ return template; }else { @@ -307,18 +313,18 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied"); } } - + TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor())); TemplateProfile profile = adapter.prepare(cmd); VMTemplateVO template = adapter.create(profile); - + if (template != null){ return template; }else { throw new CloudRuntimeException("Failed to create a template"); } } - + @Override public DataStore getImageStore(String storeUuid, Long zoneId) { DataStore imageStore = null; @@ -331,7 +337,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } imageStore = stores.get(0); } - + return imageStore; } @@ -344,7 +350,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, String url = cmd.getUrl(); String mode = cmd.getMode(); Long eventId = cmd.getStartEventId(); - + // FIXME: async job needs fixing Long uploadId = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr); if (uploadId != null){ @@ -372,16 +378,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException("Failed to extract the teamplate"); } } - + @Override public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) { - + VMTemplateVO vmTemplate = _tmpltDao.findById(templateId); if(vmTemplate == null) throw new InvalidParameterValueException("Unable to find template id=" + templateId); - + _accountMgr.checkAccess(UserContext.current().getCaller(), AccessType.ModifyEntry, true, vmTemplate); - + prepareTemplateInAllStoragePools(vmTemplate, zoneId); return vmTemplate; } @@ -392,22 +398,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, desc = Upload.Type.ISO.toString(); } eventId = eventId == null ? 0:eventId; - + if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) { throw new PermissionDeniedException("Extraction has been disabled by admin"); } - + VMTemplateVO template = _tmpltDao.findById(templateId); if (template == null || template.getRemoved() != null) { throw new InvalidParameterValueException("Unable to find " +desc+ " with id " + templateId); } - + if (template.getTemplateType() == Storage.TemplateType.SYSTEM){ throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template"); } else if (template.getTemplateType() == Storage.TemplateType.PERHOST){ throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM"); } - + if (isISO) { if (template.getFormat() != ImageFormat.ISO ){ throw new InvalidParameterValueException("Unsupported format, could not extract the ISO"); @@ -417,7 +423,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Unsupported format, could not extract the template"); } } - + if (zoneId == null && _swiftMgr.isSwiftEnabled()) { zoneId = _swiftMgr.chooseZoneForTmpltExtract(templateId); } @@ -429,13 +435,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (_dcDao.findById(zoneId) == null) { throw new IllegalArgumentException("Please specify a valid zone."); } - + if (!_accountMgr.isRootAdmin(caller.getType()) && !template.isExtractable()) { throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable"); } - + _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - + List sservers = getSecondaryStorageHosts(zoneId); VMTemplateHostVO tmpltHostRef = null; @@ -452,7 +458,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } } - + if (tmpltHostRef == null && _swiftMgr.isSwiftEnabled()) { SwiftTO swift = _swiftMgr.getSwiftTO(templateId); if (swift != null && sservers != null) { @@ -468,14 +474,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (tmpltHostRef == null) { throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); } - + Upload.Mode extractMode; if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){ throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD); } else { extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; } - + if (extractMode == Upload.Mode.FTP_UPLOAD){ URI uri = null; try { @@ -486,7 +492,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } catch (Exception ex) { throw new InvalidParameterValueException("Invalid url given: " + url); } - + String host = uri.getHost(); try { InetAddress hostAddr = InetAddress.getByName(host); @@ -499,22 +505,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } catch (UnknownHostException uhe) { throw new InvalidParameterValueException("Unable to resolve " + host); } - + if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE) ){ - throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same"); + throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same"); } - - return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr); + + return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr); } - + UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltHostRef, zoneId, eventId); - if (vo != null){ + if (vo != null){ return vo.getId(); }else{ return null; } } - + public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) { List pools = _poolDao.listByStatus(StoragePoolStatus.Up); for(final StoragePoolVO pool : pools) { @@ -528,7 +534,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.warn("Unexpected exception ", e); } } - + private void reallyRun() { s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId()); StoragePool pol = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId()); @@ -541,7 +547,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } } - + String downloadTemplateFromSwiftToSecondaryStorage(long dcId, long templateId){ VMTemplateVO template = _tmpltDao.findById(templateId); if ( template == null ) { @@ -648,7 +654,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override @DB public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) { VMTemplateVO template = _tmpltDao.findById(templ.getId(), true); - + long poolId = pool.getId(); long templateId = template.getId(); long dcId = pool.getDataCenterId(); @@ -656,23 +662,23 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, VMTemplateHostVO templateHostRef = null; long templateStoragePoolRefId; String origUrl = null; - + templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); if (templateStoragePoolRef != null) { templateStoragePoolRef.setMarkedForGC(false); _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef); - + if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) { if (s_logger.isDebugEnabled()) { s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId); } - + return templateStoragePoolRef; } } - + templateHostRef = findVmTemplateHost(templateId, pool); - + if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) { String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId); if (result != null) { @@ -691,13 +697,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return null; } } - + HostVO sh = _hostDao.findById(templateHostRef.getHostId()); origUrl = sh.getStorageUrl(); if (origUrl == null) { throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString()); } - + if (templateStoragePoolRef == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Downloading template " + templateId + " to pool " + poolId); @@ -706,7 +712,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, try { templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef); templateStoragePoolRefId = templateStoragePoolRef.getId(); - + } catch (Exception e) { s_logger.debug("Assuming we're in a race condition: " + e.getMessage()); templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); @@ -718,12 +724,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } else { templateStoragePoolRefId = templateStoragePoolRef.getId(); } - + List vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up); if (vos == null || vos.isEmpty()){ - throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool"); - } - + throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool"); + } + templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds); if (templateStoragePoolRef == null) { throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId); @@ -734,13 +740,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return templateStoragePoolRef; } String url = origUrl + "/" + templateHostRef.getInstallPath(); - PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(), + PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(), template.getAccountId(), pool, _primaryStorageDownloadWait); HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId()); assert(secondaryStorageHost != null); dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl()); - - + + for (int retry = 0; retry < 2; retry ++){ Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries StoragePoolHostVO vo = vos.get(0); @@ -749,7 +755,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } dcmd.setLocalPath(vo.getLocalPath()); // set 120 min timeout for this command - + PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend( _hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd); if (answer != null && answer.getResult() ) { @@ -776,10 +782,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return null; } - - - - + + + + @Override public VMTemplateHostVO findVmTemplateHost(long templateId, StoragePool pool) { @@ -813,7 +819,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return null; } - + @Override public String getChecksum(Long hostId, String templatePath) { HostVO ssHost = _hostDao.findById(hostId); @@ -831,7 +837,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return null; } - + @Override @DB public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) { @@ -873,22 +879,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) { // have to use the same lock that prepareTemplateForCreate use to maintain state consistency VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200); - + if (templateStoragePoolRef == null) { s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId); return false; } - + try { templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED); _tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef); } finally { _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId); } - + return true; } - + @Override @DB public boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException { @@ -930,7 +936,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } else { dstTmpltHost.setDestroyed(false); _tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost); - + return true; } } else if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOAD_ERROR){ @@ -951,7 +957,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if(_downloadMonitor.copyTemplate(template, srcSecHost, dstSecHost) ) { _tmpltDao.addTemplateToZone(template, dstZoneId); - + if(account.getId() != Account.ACCOUNT_ID_SYSTEM){ UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(), template.getClass().getName(), template.getUuid()); @@ -961,8 +967,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return false; } - - + + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true) public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException { @@ -971,7 +977,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Long sourceZoneId = cmd.getSourceZoneId(); Long destZoneId = cmd.getDestinationZoneId(); Account caller = UserContext.current().getCaller(); - + if (_swiftMgr.isSwiftEnabled()) { throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones"); } @@ -985,37 +991,37 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (sourceZoneId == destZoneId) { throw new InvalidParameterValueException("Please specify different source and destination zones."); } - + DataCenterVO sourceZone = _dcDao.findById(sourceZoneId); if (sourceZone == null) { throw new InvalidParameterValueException("Please specify a valid source zone."); } - + DataCenterVO dstZone = _dcDao.findById(destZoneId); if (dstZone == null) { throw new InvalidParameterValueException("Please specify a valid destination zone."); } - + VMTemplateVO template = _tmpltDao.findById(templateId); if (template == null || template.getRemoved() != null) { throw new InvalidParameterValueException("Unable to find template with id"); } - + HostVO dstSecHost = getSecondaryStorageHost(destZoneId, templateId); if ( dstSecHost != null ) { s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecHost.getId() + " in zone " + destZoneId + " , don't need to copy"); return template; } - + HostVO srcSecHost = getSecondaryStorageHost(sourceZoneId, templateId); if ( srcSecHost == null ) { throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId ); } - + _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - + boolean success = copy(userId, template, srcSecHost, sourceZone, dstZone); - + if (success){ return template; }else { @@ -1029,24 +1035,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template == null || template.getRemoved() != null) { throw new InvalidParameterValueException("Please specify a valid template."); } - + TemplateAdapter adapter = getAdapter(template.getHypervisorType()); return adapter.delete(new TemplateProfile(userId, template, zoneId)); } - + @Override public List getUnusedTemplatesInPool(StoragePoolVO pool) { List unusedTemplatesInPool = new ArrayList(); List allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId()); - + for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) { - VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); - + VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); + // If this is a routing template, consider it in use if (template.getTemplateType() == TemplateType.SYSTEM) { continue; } - + // If the template is not yet downloaded to the pool, consider it in use if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) { continue; @@ -1056,24 +1062,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, unusedTemplatesInPool.add(templatePoolVO); } } - + return unusedTemplatesInPool; } - + @Override public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) { StoragePool pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); - - + + if (s_logger.isDebugEnabled()) { s_logger.debug("Evicting " + templatePoolVO); } DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO); - + try { Answer answer = _storageMgr.sendToPool(pool, cmd); - + if (answer != null && answer.getResult()) { // Remove the templatePoolVO if (_tmpltPoolDao.remove(templatePoolVO.getId())) { @@ -1087,7 +1093,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - + void swiftTemplateSync() { GlobalLock swiftTemplateSyncLock = GlobalLock.getInternLock("templatemgr.swiftTemplateSync"); try { @@ -1187,7 +1193,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public boolean configure(String name, Map params) throws ConfigurationException { - + final Map configs = _configDao.getConfiguration("AgentManager", params); _routerTemplateId = NumbersUtil.parseInt(configs.get("router.template.id"), 1); @@ -1200,14 +1206,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, HostTemplateStatesSearch = _tmpltHostDao.createSearchBuilder(); HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); - + SearchBuilder HostSearch = _hostDao.createSearchBuilder(); HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - + HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER); HostSearch.done(); HostTemplateStatesSearch.done(); - + _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); _preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader")); _swiftTemplateSyncExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("swift-template-sync-Executor")); @@ -1222,7 +1228,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return true; } - + protected TemplateManagerImpl() { } @@ -1260,23 +1266,57 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return true; } + @Override + public boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef) { + VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateStoreRef.getTemplateId()); + long templateId = template.getId(); + ImageStoreVO imageStore = _imageStoreDao.findById(templateStoreRef.getDataStoreId()); + long zoneId = imageStore.getDataCenterId(); + DataCenterVO zone = _dcDao.findById(zoneId); + + // Check if there are VMs running in the template host ref's zone that use the template + List nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId); + + if (!nonExpungedVms.isEmpty()) { + s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are non-expunged VMs deployed from this template."); + return false; + } + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + //check if there is any VM using this ISO. + if (!userVmUsingIso.isEmpty()) { + s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs"); + return false; + } + // Check if there are any snapshots for the template in the template host ref's zone + List volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId); + for (VolumeVO volume : volumes) { + List snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1"); + if (!snapshots.isEmpty()) { + s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are 2.1 snapshots using this template."); + return false; + } + } + + return true; + } + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true) public boolean detachIso(long vmId) { Account caller = UserContext.current().getCaller(); Long userId = UserContext.current().getCallerUserId(); - + // Verify input parameters UserVmVO vmInstanceCheck = _userVmDao.findById(vmId); if (vmInstanceCheck == null) { throw new InvalidParameterValueException ("Unable to find a virtual machine with id " + vmId); } - + UserVm userVM = _userVmDao.findById(vmId); if (userVM == null) { throw new InvalidParameterValueException("Please specify a valid VM."); } - + _accountMgr.checkAccess(caller, null, true, userVM); Long isoId = userVM.getIsoId(); @@ -1284,7 +1324,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("The specified VM has no ISO attached to it."); } UserContext.current().setEventDetails("Vm Id: " +vmId+ " ISO Id: "+isoId); - + State vmState = userVM.getState(); if (vmState != State.Running && vmState != State.Stopped) { throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); @@ -1295,44 +1335,44 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return result; }else { throw new CloudRuntimeException("Failed to detach iso"); - } + } } - + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true) public boolean attachIso(long isoId, long vmId) { Account caller = UserContext.current().getCaller(); Long userId = UserContext.current().getCallerUserId(); - + // Verify input parameters UserVmVO vm = _userVmDao.findById(vmId); if (vm == null) { throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId); } - + VMTemplateVO iso = _tmpltDao.findById(isoId); if (iso == null || iso.getRemoved() != null) { throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId); } - + //check permissions - //check if caller has access to VM and ISO + //check if caller has access to VM and ISO //and also check if the VM's owner has access to the ISO. - + _accountMgr.checkAccess(caller, null, false, iso, vm); - + Account vmOwner = _accountDao.findById(vm.getAccountId()); _accountMgr.checkAccess(vmOwner, null, false, iso, vm); - + State vmState = vm.getState(); if (vmState != State.Running && vmState != State.Stopped) { throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); } - + if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer){ throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType()); } - + if("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) { throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType()); } @@ -1343,7 +1383,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException("Failed to attach iso"); } } - + private boolean attachISOToVM(long vmId, long isoId, boolean attach) { UserVmVO vm = this._userVmDao.findById(vmId); @@ -1397,41 +1437,43 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if ( success && attach) { vm.setIsoId(iso.getId()); _userVmDao.update(vmId, vm); - } + } if ( success && !attach ) { vm.setIsoId(null); _userVmDao.update(vmId, vm); - } + } return success; } - + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true) public boolean deleteTemplate(DeleteTemplateCmd cmd) { Long templateId = cmd.getId(); Account caller = UserContext.current().getCaller(); - + VirtualMachineTemplate template = getTemplate(templateId); if (template == null) { throw new InvalidParameterValueException("unable to find template with id " + templateId); } - + _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - + if (template.getFormat() == ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid template."); } + /* if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) { _swiftMgr.deleteTemplate(cmd); } if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) { _s3Mgr.deleteTemplate(cmd.getId(), caller.getAccountId()); } + */ TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); boolean result = adapter.delete(profile); - + if (result){ if (cmd.getZoneId() == null && (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) { @@ -1448,21 +1490,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException("Failed to delete template"); } } - + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true) public boolean deleteIso(DeleteIsoCmd cmd) { Long templateId = cmd.getId(); Account caller = UserContext.current().getCaller(); Long zoneId = cmd.getZoneId(); - + VirtualMachineTemplate template = getTemplate(templateId);; if (template == null) { throw new InvalidParameterValueException("unable to find iso with id " + templateId); } - + _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - + if (template.getFormat() != ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid iso."); } @@ -1495,17 +1537,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException("Failed to delete ISO"); } } - + @Override public VirtualMachineTemplate getTemplate(long templateId) { VMTemplateVO template = _tmpltDao.findById(templateId); if (template != null && template.getRemoved() == null) { return template; } - + return null; } - + @Override public List listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) { Account caller = UserContext.current().getCaller(); @@ -1519,7 +1561,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template == null) { throw new InvalidParameterValueException("unable to find " + cmd.getMediaType() + " with id " + id); } - + if (cmd instanceof ListTemplatePermissionsCmd) { if (template.getFormat().equals(ImageFormat.ISO)) { throw new InvalidParameterValueException("Please provide a valid template"); @@ -1544,7 +1586,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return accountNames; } - + @DB @Override public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) { @@ -1579,7 +1621,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Please provide a valid iso"); } } - + //convert projectIds to accountNames if (projectIds != null) { for (Long projectId : projectIds) { @@ -1587,7 +1629,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (project == null) { throw new InvalidParameterValueException("Unable to find project by id " + projectId); } - + if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) { throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId); } @@ -1636,7 +1678,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (isFeatured != null) { updatedTemplate.setFeatured(isFeatured.booleanValue()); } - + if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {//Only ROOT admins allowed to change this powerful attribute updatedTemplate.setExtractable(isExtractable.booleanValue()); }else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { @@ -1686,15 +1728,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return true; } - - + + private String getRandomPrivateTemplateName() { return UUID.randomUUID().toString(); } - - - - + + + + @Override @DB @@ -1733,7 +1775,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException( "Creating private Template need to specify snapshotId or volumeId"); } - + CommandResult result = null; try { result = future.get(); @@ -1742,7 +1784,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.debug("Failed to create template" + result.getResult()); throw new CloudRuntimeException("Failed to create template" + result.getResult()); } - + privateTemplate = this._tmpltDao.findById(templateId); UsageEventVO usageEvent = new UsageEventVO( EventTypes.EVENT_TEMPLATE_CREATE, @@ -1990,7 +2032,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - + @Override public Pair getAbsoluteIsoPath(long templateId, long dataCenterId) { @@ -2108,7 +2150,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return hosts; } - + @Override public Long getTemplateSize(long templateId, long zoneId) { SearchCriteria sc = HostTemplateStatesSearch.create(); @@ -2145,4 +2187,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return size; } + // find image store where this template is located + @Override + public List getImageStoreByTemplate(long templateId, Long zoneId) { + // find all eligible image stores for this zone scope + List imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + if ( imageStores == null || imageStores.size() == 0 ){ + return null; + } + List stores = new ArrayList(); + for (DataStore store : imageStores){ + // check if the template is stored there + List storeTmpl = this._tmplStoreDao.listByTemplateStore(templateId, store.getId()); + if ( storeTmpl != null && storeTmpl.size() > 0 ){ + stores.add(store); + } + } + return stores; + } + + } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index e8739fc71c4..65eedee9dbb 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -140,7 +140,7 @@ CREATE TABLE `cloud`.`template_store_ref` ( INDEX `i_template_store_ref__template_id`(`template_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -ALTER TABLE `cloud`.`vm_template` ADD COLUMN `image_data_store_id` bigint unsigned; +-- ALTER TABLE `cloud`.`vm_template` ADD COLUMN `image_data_store_id` bigint unsigned; -- Do we still need these columns? TODO, to delete them, remove FK constraints from snapshots table -- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `swift_id`; From 1b3994e180528aa7b0fe322083507fd67d208d7e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 16 Apr 2013 16:38:14 -0700 Subject: [PATCH 027/303] Fix copyTemplateCmd. --- .../agent/api/storage/DownloadCommand.java | 5 +- .../datastore/db/TemplateDataStoreDao.java | 2 + .../storage/image/TemplateServiceImpl.java | 12 +- .../test/DirectAgentManagerSimpleImpl.java | 26 +- .../image/db/TemplateDataStoreDaoImpl.java | 13 + .../storage/volume/VolumeServiceImpl.java | 6 +- .../CloudStackImageStoreDriverImpl.java | 5 +- server/src/com/cloud/agent/AgentManager.java | 34 +- .../cloud/agent/manager/AgentManagerImpl.java | 14 + .../com/cloud/storage/StorageManagerImpl.java | 4 +- .../storage/download/DownloadMonitor.java | 3 +- .../storage/download/DownloadMonitorImpl.java | 634 +++++++++--------- .../com/cloud/template/TemplateManager.java | 9 +- .../cloud/template/TemplateManagerImpl.java | 111 ++- .../com/cloud/agent/MockAgentManagerImpl.java | 16 +- 15 files changed, 499 insertions(+), 395 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/api/src/com/cloud/agent/api/storage/DownloadCommand.java index 77e7ae32b68..81577b5dec6 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadCommand.java @@ -147,9 +147,10 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal this.resourceType = ResourceType.VOLUME; } - public DownloadCommand(String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { + public DownloadCommand(DataStoreTO store, String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { super(template.getUniqueName(), url, template.getFormat(), template.getAccountId()); - this.hvm = template.isRequiresHvm(); + this._store = store; + this.hvm = template.isRequiresHvm(); this.checksum = template.getChecksum(); this.id = template.getId(); this.description = template.getDisplayText(); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index d1679a6989d..e9485267174 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -44,6 +44,8 @@ public interface TemplateDataStoreDao extends GenericDao listByTemplate(long templateId); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 38381082216..c16e47c7ee4 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -388,8 +388,7 @@ public class TemplateServiceImpl implements TemplateService { VMTemplateVO template = _templateDao.findById(tInfo.getId()); DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), store.getUri(), tInfo.getInstallPath(), template.getId(), template.getAccountId()); try { - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); + _agentMgr.sendToSecStorage(store, dtCommand, null); } catch (AgentUnavailableException e) { String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database"; s_logger.error(err); @@ -430,16 +429,15 @@ public class TemplateServiceImpl implements TemplateService { } - private Map listTemplate(DataStore ssHost) { - ListTemplateCommand cmd = new ListTemplateCommand(ssHost.getUri()); - HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssHost); - Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd); + private Map listTemplate(DataStore ssStore) { + ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getUri()); + Answer answer = _agentMgr.sendToSecStorage(ssStore, cmd); if (answer != null && answer.getResult()) { ListTemplateAnswer tanswer = (ListTemplateAnswer)answer; return tanswer.getTemplateInfo(); } else { if (s_logger.isDebugEnabled()) { - s_logger.debug("can not list template for secondary storage host " + ssHost.getId()); + s_logger.debug("can not list template for secondary storage host " + ssStore.getId()); } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index 575bc8e2ba2..0725971ab08 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -24,6 +24,7 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -91,12 +92,12 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa params.put("password", "password"); params.put("zone", String.valueOf(host.getDataCenterId())); params.put("pod", String.valueOf(host.getPodId())); - + ServerResource resource = null; if (host.getHypervisorType() == HypervisorType.XenServer) { resource = new XcpOssResource(); } - + try { resource.configure(host.getName(), params); hostResourcesMap.put(hostId, resource); @@ -106,7 +107,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa HostEnvironment env = new HostEnvironment(); SetupCommand cmd = new SetupCommand(env); cmd.setNeedSetup(true); - + resource.executeRequest(cmd); } @@ -117,11 +118,11 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa loadResource(hostId); resource = hostResourcesMap.get(hostId); } - + if (resource == null) { return null; } - + Answer answer = resource.executeRequest(cmd); return answer; } @@ -186,6 +187,19 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } + + @Override + public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException { + // TODO Auto-generated method stub + + } + + @Override + public Answer sendToSecStorage(DataStore ssStore, Command cmd) { + // TODO Auto-generated method stub + return null; + } + @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub @@ -243,7 +257,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa @Override public void disconnectWithInvestigation(long hostId, Event event) { // TODO Auto-generated method stub - + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index dd8e319323f..eccb02aff4e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -206,6 +206,19 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = storeTemplateSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + if (!lock) + return findOneIncludingRemovedBy(sc); + else + return lockOneRandomRow(sc, true); + } + @Override public TemplateDataStoreVO findByTemplate(long templateId) { SearchCriteria sc = templateSearch.create(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index d017f4f3600..22320957e63 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -814,8 +814,7 @@ public class VolumeServiceImpl implements VolumeService { TemplateProp vInfo = volumeInfos.get(uniqueName); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getUri(), vInfo.getInstallPath()); try { - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - _agentMgr.sendToSecStorage(ssAhost, dtCommand, null); + _agentMgr.sendToSecStorage(store, dtCommand, null); } catch (AgentUnavailableException e) { String err = "Failed to delete " + vInfo.getTemplateName() + " on image store " + storeId + " which isn't in the database"; s_logger.error(err); @@ -830,8 +829,7 @@ public class VolumeServiceImpl implements VolumeService { private Map listVolume(DataStore store) { ListVolumeCommand cmd = new ListVolumeCommand(store.getUri()); - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - Answer answer = _agentMgr.sendToSecStorage(ssAhost, cmd); + Answer answer = _agentMgr.sendToSecStorage(store, cmd); if (answer != null && answer.getResult()) { ListVolumeAnswer tanswer = (ListVolumeAnswer)answer; return tanswer.getTemplateInfo(); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 85ebd230071..fe556a2401d 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -236,12 +236,11 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { List userVmUsingIso = _userVmDao.listByIsoId(templateId); // check if there is any VM using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - // get installpath of this template on image store + // get installpath of this template on image store TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage(ssAhost, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to deleted template at store: " + store.getName()); diff --git a/server/src/com/cloud/agent/AgentManager.java b/server/src/com/cloud/agent/AgentManager.java index 6c300ea76fa..8071f28db17 100755 --- a/server/src/com/cloud/agent/AgentManager.java +++ b/server/src/com/cloud/agent/AgentManager.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.agent; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; @@ -44,10 +46,10 @@ public interface AgentManager extends Manager { Del, Contains, } - + /** * easy send method that returns null if there's any errors. It handles all exceptions. - * + * * @param hostId * host id * @param cmd @@ -58,7 +60,7 @@ public interface AgentManager extends Manager { /** * Synchronous sending a command to the agent. - * + * * @param hostId * id of the agent on host * @param cmd @@ -70,7 +72,7 @@ public interface AgentManager extends Manager { /** * Synchronous sending a list of commands to the agent. - * + * * @param hostId * id of the agent on host * @param cmds @@ -87,7 +89,7 @@ public interface AgentManager extends Manager { /** * Asynchronous sending of a command to the agent. - * + * * @param hostId * id of the agent on the host. * @param cmds @@ -102,7 +104,7 @@ public interface AgentManager extends Manager { /** * Register to listen for host events. These are mostly connection and disconnection events. - * + * * @param listener * @param connections * listen for connections @@ -125,7 +127,7 @@ public interface AgentManager extends Manager { /** * Unregister for listening to host events. - * + * * @param id * returned from registerForHostEvents */ @@ -138,20 +140,24 @@ public interface AgentManager extends Manager { void sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) throws AgentUnavailableException; Answer sendToSecStorage(HostVO ssHost, Command cmd); - + + void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException; + + Answer sendToSecStorage(DataStore ssStore, Command cmd); + /* working as a lock while agent is being loaded */ public boolean tapLoadingAgents(Long hostId, TapAgentsAction action); - + public AgentAttache handleDirectConnectAgent(HostVO host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance) throws ConnectionException; - + public boolean agentStatusTransitTo(HostVO host, Status.Event e, long msId); - + public AgentAttache findAttache(long hostId); - + void disconnectWithoutInvestigation(long hostId, Status.Event event); - + public void pullAgentToMaintenance(long hostId); - + public void pullAgentOutMaintenance(long hostId); boolean reconnect(long hostId); diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index 6baeecf382a..c839b82719b 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -39,6 +39,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -380,6 +381,18 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl return attache; } + @Override + public Answer sendToSecStorage(DataStore ssStore, Command cmd) { + HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore); + return easySend(ssAhost.getId(), cmd); + } + + @Override + public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException { + HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore); + send(ssAhost.getId(), new Commands(cmd), listener); + } + @Override public Answer sendToSecStorage(HostVO ssHost, Command cmd) { if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) { @@ -406,6 +419,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } } + private void sendToSSVM(final long dcId, final Command cmd, final Listener listener) throws AgentUnavailableException { List ssAHosts = _ssvmMgr.listUpAndConnectingSecondaryStorageVmHost(dcId); if (ssAHosts == null || ssAHosts.isEmpty() ) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index cd15167f3fe..d46b2c61369 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1266,11 +1266,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C String installPath = destroyedTemplateStoreVO .getInstallPath(); - HostVO ssAhost = this._ssvmMgr.pickSsvmHost(store); if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage( - ssAhost, + Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand( store.getTO(), store.getUri(), diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index b5a3f8592b9..e709e90ff70 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -22,7 +22,6 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import com.cloud.exception.StorageUnavailableException; -import com.cloud.host.HostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.Storage.ImageFormat; @@ -38,7 +37,7 @@ public interface DownloadMonitor extends Manager{ public void cancelAllDownloads(Long templateId); - public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer) + public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store) throws StorageUnavailableException; //void addSystemVMTemplatesToHost(HostVO host, Map templateInfos); diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 58477b43e90..50ded27e349 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -106,10 +106,9 @@ import com.cloud.vm.dao.UserVmDao; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - @Component -@Local(value={DownloadMonitor.class}) -public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor { +@Local(value = { DownloadMonitor.class }) +public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor { static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class); @Inject @@ -119,7 +118,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject VMTemplateZoneDao _vmTemplateZoneDao; @Inject - VMTemplatePoolDao _vmTemplatePoolDao; + VMTemplatePoolDao _vmTemplatePoolDao; @Inject VMTemplateSwiftDao _vmTemplateSwiftlDao; @Inject @@ -139,27 +138,27 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject SecondaryStorageVmManager _ssvmMgr; @Inject - StorageManager _storageMgr ; + StorageManager _storageMgr; @Inject private final DataCenterDao _dcDao = null; @Inject - VMTemplateDao _templateDao = null; + VMTemplateDao _templateDao = null; @Inject - private AgentManager _agentMgr; - @Inject SecondaryStorageVmManager _secMgr; + private AgentManager _agentMgr; + @Inject + SecondaryStorageVmManager _secMgr; @Inject ConfigurationDao _configDao; @Inject UserVmManager _vmMgr; - @Inject TemplateManager templateMgr; - + @Inject + TemplateManager templateMgr; @Inject private UsageEventDao _usageEventDao; - @Inject private ClusterDao _clusterDao; @Inject @@ -175,34 +174,34 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject protected AccountManager _accountMgr; - private Boolean _sslCopy = new Boolean(false); - private String _copyAuthPasswd; - private String _proxy = null; + private Boolean _sslCopy = new Boolean(false); + private String _copyAuthPasswd; + private String _proxy = null; protected SearchBuilder ReadyTemplateStatesSearch; - Timer _timer; + Timer _timer; - @Inject DataStoreManager storeMgr; + @Inject + DataStoreManager storeMgr; final Map _listenerTemplateMap = new ConcurrentHashMap(); - final Map _listenerMap = new ConcurrentHashMap(); - final Map _listenerVolumeMap = new ConcurrentHashMap(); - final Map _listenerVolMap = new ConcurrentHashMap(); + final Map _listenerMap = new ConcurrentHashMap(); + final Map _listenerVolumeMap = new ConcurrentHashMap(); + final Map _listenerVolMap = new ConcurrentHashMap(); + public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException { + _agentMgr.send(hostId, new Commands(cmd), listener); + } - public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException { - _agentMgr.send(hostId, new Commands(cmd), listener); - } - - @Override - public boolean configure(String name, Map params) { + @Override + public boolean configure(String name, Map params) { final Map configs = _configDao.getConfiguration("ManagementServer", params); _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy")); _proxy = configs.get(Config.SecStorageProxy.key()); String cert = configs.get("secstorage.ssl.cert.domain"); if (!"realhostip.com".equalsIgnoreCase(cert)) { - s_logger.warn("Only realhostip.com ssl cert is supported, ignoring self-signed and other certs"); + s_logger.warn("Only realhostip.com ssl cert is supported, ignoring self-signed and other certs"); } _copyAuthPasswd = configs.get("secstorage.copy.password"); @@ -222,382 +221,387 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor TemplatesWithNoChecksumSearch.done(); ReadyTemplateStatesSearch.done(); - return true; - } + return true; + } - @Override - public boolean start() { - _timer = new Timer(); - return true; - } + @Override + public boolean start() { + _timer = new Timer(); + return true; + } - @Override - public boolean stop() { - return true; - } + @Override + public boolean stop() { + return true; + } - public boolean isTemplateUpdateable(Long templateId, Long storeId) { - List downloadsInProgress = - _vmTemplateStoreDao.listByTemplateStoreDownloadStatus(templateId, storeId, Status.DOWNLOAD_IN_PROGRESS, Status.DOWNLOADED ); - return (downloadsInProgress.size() == 0); - } + public boolean isTemplateUpdateable(Long templateId, Long storeId) { + List downloadsInProgress = _vmTemplateStoreDao.listByTemplateStoreDownloadStatus(templateId, storeId, + Status.DOWNLOAD_IN_PROGRESS, Status.DOWNLOADED); + return (downloadsInProgress.size() == 0); + } - @Override - public boolean copyTemplate(VMTemplateVO template, HostVO sourceServer, HostVO destServer) throws StorageUnavailableException{ + // TODO: consider using dataMotionStrategy later + @Override + public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore destStore) throws StorageUnavailableException { - boolean downloadJobExists = false; - VMTemplateHostVO destTmpltHost = null; - VMTemplateHostVO srcTmpltHost = null; + boolean downloadJobExists = false; + TemplateDataStoreVO destTmpltStore = null; + TemplateDataStoreVO srcTmpltStore = null; - srcTmpltHost = _vmTemplateHostDao.findByHostTemplate(sourceServer.getId(), template.getId()); - if (srcTmpltHost == null) { - throw new InvalidParameterValueException("Template " + template.getName() + " not associated with " + sourceServer.getName()); + srcTmpltStore = this._vmTemplateStoreDao.findByStoreTemplate(sourceStore.getId(), template.getId()); + if (srcTmpltStore == null) { + throw new InvalidParameterValueException("Template " + template.getName() + " not associated with " + sourceStore.getName()); } - String url = generateCopyUrl(sourceServer, srcTmpltHost); - if (url == null) { - s_logger.warn("Unable to start/resume copy of template " + template.getUniqueName() + " to " + destServer.getName() + ", no secondary storage vm in running state in source zone"); - throw new CloudRuntimeException("No secondary VM in running state in zone " + sourceServer.getDataCenterId()); - } - destTmpltHost = _vmTemplateHostDao.findByHostTemplate(destServer.getId(), template.getId()); - if (destTmpltHost == null) { - destTmpltHost = new VMTemplateHostVO(destServer.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, url); - destTmpltHost.setCopy(true); - destTmpltHost.setPhysicalSize(srcTmpltHost.getPhysicalSize()); - _vmTemplateHostDao.persist(destTmpltHost); - } else if ((destTmpltHost.getJobId() != null) && (destTmpltHost.getJobId().length() > 2)) { + // generate a storage url on ssvm to copy from + String url = generateCopyUrl(sourceStore, srcTmpltStore); + if (url == null) { + s_logger.warn("Unable to start/resume copy of template " + template.getUniqueName() + " to " + destStore.getName() + + ", no secondary storage vm in running state in source zone"); + throw new CloudRuntimeException("No secondary VM in running state in zone " + sourceStore.getScope().getScopeId()); + } + destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), template.getId()); + if (destTmpltStore == null) { + destTmpltStore = new TemplateDataStoreVO(destStore.getId(), template.getId(), new Date(), 0, + VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, url); + destTmpltStore.setCopy(true); + destTmpltStore.setPhysicalSize(srcTmpltStore.getPhysicalSize()); + _vmTemplateStoreDao.persist(destTmpltStore); + } else if ((destTmpltStore.getJobId() != null) && (destTmpltStore.getJobId().length() > 2)) { downloadJobExists = true; } Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); - if (srcTmpltHost.getSize() > maxTemplateSizeInBytes){ - throw new CloudRuntimeException("Cant copy the template as the template's size " +srcTmpltHost.getSize()+ - " is greater than max.template.iso.size " + maxTemplateSizeInBytes); + if (srcTmpltStore.getSize() > maxTemplateSizeInBytes) { + throw new CloudRuntimeException("Cant copy the template as the template's size " + srcTmpltStore.getSize() + + " is greater than max.template.iso.size " + maxTemplateSizeInBytes); } - if(destTmpltHost != null) { - start(); - String sourceChecksum = this.templateMgr.getChecksum(srcTmpltHost.getHostId(), srcTmpltHost.getInstallPath()); - DownloadCommand dcmd = - new DownloadCommand(destServer.getStorageUrl(), url, template, TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes); - dcmd.setProxy(getHttpProxy()); - if (downloadJobExists) { - dcmd = new DownloadProgressCommand(dcmd, destTmpltHost.getJobId(), RequestType.GET_OR_RESTART); - } - dcmd.setChecksum(sourceChecksum); // We need to set the checksum as the source template might be a compressed url and have cksum for compressed image. Bug #10775 - HostVO ssAhost = _ssvmMgr.pickSsvmHost(destServer); - if( ssAhost == null ) { - s_logger.warn("There is no secondary storage VM for secondary storage host " + destServer.getName()); - return false; - } - DownloadListener dl = new DownloadListener(ssAhost, destServer, template, _timer, _vmTemplateHostDao, destTmpltHost.getId(), this, dcmd, _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr); + if (destTmpltStore != null) { + start(); + String sourceChecksum = this.templateMgr.getChecksum(sourceStore, srcTmpltStore.getInstallPath()); + DownloadCommand dcmd = new DownloadCommand(destStore.getTO(), destStore.getUri(), url, template, + TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes); + dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { - dl.setCurrState(destTmpltHost.getDownloadState()); + dcmd = new DownloadProgressCommand(dcmd, destTmpltStore.getJobId(), RequestType.GET_OR_RESTART); + } + dcmd.setChecksum(sourceChecksum); // We need to set the checksum as + // the source template might be a + // compressed url and have cksum + // for compressed image. Bug + // #10775 + HostVO ssAhost = _ssvmMgr.pickSsvmHost(destStore); + if (ssAhost == null) { + s_logger.warn("There is no secondary storage VM for secondary storage host " + destStore.getName()); + return false; + } + DownloadListener dl = new DownloadListener(ssAhost, destStore, template, _timer, _vmTemplateStoreDao, destTmpltStore.getId(), this, dcmd, + _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, null); + if (downloadJobExists) { + dl.setCurrState(destTmpltStore.getDownloadState()); + } + DownloadListener old = null; + synchronized (_listenerTemplateMap) { + old = _listenerTemplateMap.put(destTmpltStore, dl); + } + if (old != null) { + old.abandon(); } - DownloadListener old = null; - synchronized (_listenerMap) { - old = _listenerMap.put(destTmpltHost, dl); - } - if( old != null ) { - old.abandon(); - } try { - send(ssAhost.getId(), dcmd, dl); - return true; + send(ssAhost.getId(), dcmd, dl); + return true; } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume COPY of template " + template.getUniqueName() + " to " + destServer.getName(), e); - dl.setDisconnected(); - dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); - e.printStackTrace(); + s_logger.warn("Unable to start /resume COPY of template " + template.getUniqueName() + " to " + destStore.getName(), e); + dl.setDisconnected(); + dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); + e.printStackTrace(); } - } + } - return false; - } + return false; + } - private String generateCopyUrl(String ipAddress, String dir, String path){ - String hostname = ipAddress; - String scheme = "http"; - if (_sslCopy) { - hostname = ipAddress.replace(".", "-"); - hostname = hostname + ".realhostip.com"; - scheme = "https"; - } - return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path; - } + private String generateCopyUrl(String ipAddress, String dir, String path) { + String hostname = ipAddress; + String scheme = "http"; + if (_sslCopy) { + hostname = ipAddress.replace(".", "-"); + hostname = hostname + ".realhostip.com"; + scheme = "https"; + } + return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path; + } - private String generateCopyUrl(HostVO sourceServer, VMTemplateHostVO srcTmpltHost) { - List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, sourceServer.getDataCenterId(), State.Running); - if (ssVms.size() > 0) { - SecondaryStorageVmVO ssVm = ssVms.get(0); - if (ssVm.getPublicIpAddress() == null) { - s_logger.warn("A running secondary storage vm has a null public ip?"); - return null; - } - return generateCopyUrl(ssVm.getPublicIpAddress(), sourceServer.getParent(), srcTmpltHost.getInstallPath()); - } + private String generateCopyUrl(DataStore sourceServer, TemplateDataStoreVO srcTmpltStore) { + List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, sourceServer + .getScope().getScopeId(), State.Running); + if (ssVms.size() > 0) { + SecondaryStorageVmVO ssVm = ssVms.get(0); + if (ssVm.getPublicIpAddress() == null) { + s_logger.warn("A running secondary storage vm has a null public ip?"); + return null; + } + //TODO: how to handle parent field from hostVO in image_store? and how we can populate that column? + // return generateCopyUrl(ssVm.getPublicIpAddress(), sourceServer.getParent(), srcTmpltStore.getInstallPath()); + return generateCopyUrl(ssVm.getPublicIpAddress(), null, srcTmpltStore.getInstallPath()); + } - VMTemplateVO tmplt = _templateDao.findById(srcTmpltHost.getTemplateId()); - HypervisorType hyperType = tmplt.getHypervisorType(); - /*No secondary storage vm yet*/ - if (hyperType != null && hyperType == HypervisorType.KVM) { - return "file://" + sourceServer.getParent() + "/" + srcTmpltHost.getInstallPath(); - } - return null; - } + VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId()); + HypervisorType hyperType = tmplt.getHypervisorType(); + /*No secondary storage vm yet*/ + if (hyperType != null && hyperType == HypervisorType.KVM) { + //return "file://" + sourceServer.getParent() + "/" + srcTmpltStore.getInstallPath(); + return "file://" + "/" + srcTmpltStore.getInstallPath(); + } + return null; + } - private void initiateTemplateDownload(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { - boolean downloadJobExists = false; + private void initiateTemplateDownload(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); if (vmTemplateStore == null) { - // This method can be invoked other places, for example, handleTemplateSync, in that case, vmTemplateStore may be null - vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); + // This method can be invoked other places, for example, + // handleTemplateSync, in that case, vmTemplateStore may be null + vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, + VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); _vmTemplateStoreDao.persist(vmTemplateStore); - } else - if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { + } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { downloadJobExists = true; } Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); String secUrl = store.getUri(); - if(vmTemplateStore != null) { - start(); - DownloadCommand dcmd = - new DownloadCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); - dcmd.setProxy(getHttpProxy()); - if (downloadJobExists) { - dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); - } - if (vmTemplateStore.isCopy()) { - dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); - } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - if( ssAhost == null ) { - s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName()); - return; - } - DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); - if (downloadJobExists) { - // due to handling existing download job issues, we still keep downloadState in template_store_ref to avoid big change in DownloadListener to use - // new ObjectInDataStore.State transition. TODO: fix this later to be able to remove downloadState from template_store_ref. - dl.setCurrState(vmTemplateStore.getDownloadState()); - } + if (vmTemplateStore != null) { + start(); + DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); + dcmd.setProxy(getHttpProxy()); + if (downloadJobExists) { + dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); + } + if (vmTemplateStore.isCopy()) { + dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); + } + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + if (ssAhost == null) { + s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName()); + return; + } + DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, + _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + if (downloadJobExists) { + // due to handling existing download job issues, we still keep + // downloadState in template_store_ref to avoid big change in + // DownloadListener to use + // new ObjectInDataStore.State transition. TODO: fix this later + // to be able to remove downloadState from template_store_ref. + dl.setCurrState(vmTemplateStore.getDownloadState()); + } DownloadListener old = null; synchronized (_listenerTemplateMap) { old = _listenerTemplateMap.put(vmTemplateStore, dl); } - if( old != null ) { + if (old != null) { old.abandon(); } - try { - send(ssAhost.getId(), dcmd, dl); + try { + send(ssAhost.getId(), dcmd, dl); } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + store.getName(), e); - dl.setDisconnected(); - dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); + s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + store.getName(), e); + dl.setDisconnected(); + dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } - } - } + } + } - - - @Override - public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + @Override + public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); if (isTemplateUpdateable(templateId, store.getId())) { - if ( template != null && template.getUrl() != null ){ + if (template != null && template.getUrl() != null) { initiateTemplateDownload(template, store, callback); } } - } + } - - @Override - public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback) { - boolean downloadJobExists = false; + @Override + public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, + AsyncCompletionCallback callback) { + boolean downloadJobExists = false; VolumeDataStoreVO volumeHost = null; volumeHost = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId()); if (volumeHost == null) { - volumeHost = new VolumeDataStoreVO(store.getId(), volume.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, - "jobid0000", null, url, checkSum, format); + volumeHost = new VolumeDataStoreVO(store.getId(), volume.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, + null, null, "jobid0000", null, url, checkSum, format); _volumeStoreDao.persist(volumeHost); } else if ((volumeHost.getJobId() != null) && (volumeHost.getJobId().length() > 2)) { downloadJobExists = true; } - Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes(); String secUrl = store.getUri(); - if(volumeHost != null) { - start(); - DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format); - dcmd.setProxy(getHttpProxy()); - if (downloadJobExists) { - dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); - dcmd.setResourceType(ResourceType.VOLUME); - } + if (volumeHost != null) { + start(); + DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format); + dcmd.setProxy(getHttpProxy()); + if (downloadJobExists) { + dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); + dcmd.setResourceType(ResourceType.VOLUME); + } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - if( ssAhost == null ) { - s_logger.warn("There is no secondary storage VM for image store " + store.getName()); - return; - } - DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(), - this, dcmd, _volumeDao, _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); + if (ssAhost == null) { + s_logger.warn("There is no secondary storage VM for image store " + store.getName()); + return; + } + DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(), this, dcmd, _volumeDao, + _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback); - if (downloadJobExists) { - dl.setCurrState(volumeHost.getDownloadState()); - } + if (downloadJobExists) { + dl.setCurrState(volumeHost.getDownloadState()); + } DownloadListener old = null; synchronized (_listenerVolMap) { old = _listenerVolMap.put(volumeHost, dl); } - if( old != null ) { + if (old != null) { old.abandon(); } - try { - send(ssAhost.getId(), dcmd, dl); + try { + send(ssAhost.getId(), dcmd, dl); } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e); - dl.setDisconnected(); - dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); + s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e); + dl.setDisconnected(); + dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } - } - } + } + } + @DB + public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { + if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { + VMTemplateHostVO vmTemplateHost = new VMTemplateHostVO(host.getId(), template.getId()); + synchronized (_listenerMap) { + _listenerMap.remove(vmTemplateHost); + } + } - @DB - public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { - if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus==Status.ABANDONED)){ - VMTemplateHostVO vmTemplateHost = new VMTemplateHostVO(host.getId(), template.getId()); - synchronized (_listenerMap) { - _listenerMap.remove(vmTemplateHost); - } - } + VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId()); - VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId()); - - Transaction txn = Transaction.currentTxn(); + Transaction txn = Transaction.currentTxn(); txn.start(); if (dnldStatus == Status.DOWNLOADED) { long size = -1; - if(vmTemplateHost!=null){ + if (vmTemplateHost != null) { size = vmTemplateHost.getPhysicalSize(); template.setSize(size); this._templateDao.update(template.getId(), template); - } - else{ + } else { s_logger.warn("Failed to get size for template" + template.getName()); } String eventType = EventTypes.EVENT_TEMPLATE_CREATE; - if((template.getFormat()).equals(ImageFormat.ISO)){ + if ((template.getFormat()).equals(ImageFormat.ISO)) { eventType = EventTypes.EVENT_ISO_CREATE; } - if(template.getAccountId() != Account.ACCOUNT_ID_SYSTEM){ - UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(), - template.getId(), template.getName(), null, template.getSourceTemplateId(), size, - template.getClass().getName(), template.getUuid()); + if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { + UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(), + null, template.getSourceTemplateId(), size, template.getClass().getName(), template.getUuid()); } } txn.commit(); - } + } - @DB - public void handleDownloadEvent(HostVO host, VolumeVO volume, Status dnldStatus) { - if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus==Status.ABANDONED)){ - VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId()); - synchronized (_listenerVolumeMap) { - _listenerVolumeMap.remove(volumeHost); - } - } + @DB + public void handleDownloadEvent(HostVO host, VolumeVO volume, Status dnldStatus) { + if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { + VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId()); + synchronized (_listenerVolumeMap) { + _listenerVolumeMap.remove(volumeHost); + } + } - VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId()); + VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId()); - Transaction txn = Transaction.currentTxn(); + Transaction txn = Transaction.currentTxn(); txn.start(); if (dnldStatus == Status.DOWNLOADED) { - //Create usage event + // Create usage event long size = -1; - if(volumeHost!=null){ + if (volumeHost != null) { size = volumeHost.getPhysicalSize(); volume.setSize(size); this._volumeDao.update(volume.getId(), volume); - } - else{ + } else { s_logger.warn("Failed to get size for volume" + volume.getName()); } String eventType = EventTypes.EVENT_VOLUME_UPLOAD; - if(volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM){ - UsageEventUtils.publishUsageEvent(eventType, volume.getAccountId(), host.getDataCenterId(), - volume.getId(), volume.getName(), null, 0l, size, volume.getClass().getName(), volume.getUuid()); + if (volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { + UsageEventUtils.publishUsageEvent(eventType, volume.getAccountId(), host.getDataCenterId(), volume.getId(), volume.getName(), null, + 0l, size, volume.getClass().getName(), volume.getUuid()); } - }else if (dnldStatus == Status.DOWNLOAD_ERROR || dnldStatus == Status.ABANDONED || dnldStatus == Status.UNKNOWN){ - //Decrement the volume and secondary storage space count - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), - com.cloud.configuration.Resource.ResourceType.volume); + } else if (dnldStatus == Status.DOWNLOAD_ERROR || dnldStatus == Status.ABANDONED || dnldStatus == Status.UNKNOWN) { + // Decrement the volume and secondary storage space count + _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), com.cloud.configuration.Resource.ResourceType.volume); _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } txn.commit(); - } + } - - - /* + /* @Override - public void addSystemVMTemplatesToHost(HostVO host, Map templateInfos){ - if ( templateInfos == null ) { - return; - } - Long hostId = host.getId(); - List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - for ( VMTemplateVO tmplt : rtngTmplts ) { - TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName()); - if ( tmpltInfo == null ) { - continue; - } - VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(hostId, tmplt.getId()); - if ( tmpltHost == null ) { + public void addSystemVMTemplatesToHost(HostVO host, Map templateInfos){ + if ( templateInfos == null ) { + return; + } + Long hostId = host.getId(); + List rtngTmplts = _templateDao.listAllSystemVMTemplates(); + for ( VMTemplateVO tmplt : rtngTmplts ) { + TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName()); + if ( tmpltInfo == null ) { + continue; + } + VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(hostId, tmplt.getId()); + if ( tmpltHost == null ) { tmpltHost = new VMTemplateHostVO(hostId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); - tmpltHost.setSize(tmpltInfo.getSize()); - tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize()); - _vmTemplateHostDao.persist(tmpltHost); - } - } - } + tmpltHost.setSize(tmpltInfo.getSize()); + tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize()); + _vmTemplateHostDao.persist(tmpltHost); + } + } + } */ + @Override + public void cancelAllDownloads(Long templateId) { + List downloadsInProgress = _vmTemplateHostDao.listByTemplateStates(templateId, + VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.NOT_DOWNLOADED); + if (downloadsInProgress.size() > 0) { + for (VMTemplateHostVO vmthvo : downloadsInProgress) { + DownloadListener dl = null; + synchronized (_listenerMap) { + dl = _listenerMap.remove(vmthvo); + } + if (dl != null) { + dl.abandon(); + s_logger.info("Stopping download of template " + templateId + " to storage server " + vmthvo.getHostId()); + } + } + } + } - - @Override - public void cancelAllDownloads(Long templateId) { - List downloadsInProgress = - _vmTemplateHostDao.listByTemplateStates(templateId, VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.NOT_DOWNLOADED); - if (downloadsInProgress.size() > 0){ - for (VMTemplateHostVO vmthvo: downloadsInProgress) { - DownloadListener dl = null; - synchronized (_listenerMap) { - dl = _listenerMap.remove(vmthvo); - } - if (dl != null) { - dl.abandon(); - s_logger.info("Stopping download of template " + templateId + " to storage server " + vmthvo.getHostId()); - } - } - } - } - - /* - private void checksumSync(long hostId){ + /* + private void checksumSync(long hostId){ SearchCriteria sc = ReadyTemplateStatesSearch.create(); sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready); sc.setParameters("host_id", hostId); @@ -613,38 +617,36 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor _templateDao.update(template.getId(), template); } - } - */ + } + */ - private Long getMaxTemplateSizeInBytes() { - try { - return Long.parseLong(_configDao.getValue("max.template.iso.size")) * 1024L * 1024L * 1024L; - } catch (NumberFormatException e) { - return null; - } - } + private Long getMaxTemplateSizeInBytes() { + try { + return Long.parseLong(_configDao.getValue("max.template.iso.size")) * 1024L * 1024L * 1024L; + } catch (NumberFormatException e) { + return null; + } + } - private Long getMaxVolumeSizeInBytes() { - try { - return Long.parseLong(_configDao.getValue("storage.max.volume.upload.size")) * 1024L * 1024L * 1024L; - } catch (NumberFormatException e) { - return null; - } - } - - private Proxy getHttpProxy() { - if (_proxy == null) { - return null; - } - try { - URI uri = new URI(_proxy); - Proxy prx = new Proxy(uri); - return prx; - } catch (URISyntaxException e) { - return null; - } - } + private Long getMaxVolumeSizeInBytes() { + try { + return Long.parseLong(_configDao.getValue("storage.max.volume.upload.size")) * 1024L * 1024L * 1024L; + } catch (NumberFormatException e) { + return null; + } + } + private Proxy getHttpProxy() { + if (_proxy == null) { + return null; + } + try { + URI uri = new URI(_proxy); + Proxy prx = new Proxy(uri); + return prx; + } catch (URISyntaxException e) { + return null; + } + } } - diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index a5d94824e30..7c806447bc5 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -55,15 +55,14 @@ public interface TemplateManager extends TemplateApiService{ * Copies a template from its current secondary storage server to the secondary storage server in the specified zone. * * @param template - * @param srcSecHost - * @param srcZone + * @param srcSecStore * @param destZone * @return true if success * @throws InternalErrorException * @throws StorageUnavailableException * @throws ResourceAllocationException */ - boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException; + boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException; /** * Deletes a template from secondary storage servers @@ -107,6 +106,8 @@ public interface TemplateManager extends TemplateApiService{ HostVO getSecondaryStorageHost(long zoneId, long tmpltId); + DataStore getImageStore(long zoneId, long tmpltId); + VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, boolean readyOnly); @@ -120,6 +121,8 @@ public interface TemplateManager extends TemplateApiService{ String getChecksum(Long hostId, String templatePath); + String getChecksum(DataStore store, String templatePath); + List getImageStoreByTemplate(long templateId, Long zoneId); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index a4eb35c9620..e9729e4ff31 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -125,6 +125,7 @@ import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; @@ -838,6 +839,20 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return null; } + @Override + public String getChecksum(DataStore store, String templatePath) { + + String secUrl = store.getUri(); + Answer answer; + answer = _agentMgr.sendToSecStorage(store, new ComputeChecksumCommand( + secUrl, templatePath)); + if (answer != null && answer.getResult()) { + return answer.getDetails(); + } + return null; + } + + @Override @DB public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) { @@ -897,18 +912,20 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override @DB - public boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException { - List dstSecHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dstZone.getId()); + public boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException { long tmpltId = template.getId(); long dstZoneId = dstZone.getId(); - if (dstSecHosts == null || dstSecHosts.isEmpty() ) { - throw new StorageUnavailableException("Destination zone is not ready", DataCenter.class, dstZone.getId()); + // find all eligible image stores for the destination zone + List dstSecStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId)); + if (dstSecStores == null || dstSecStores.isEmpty() ) { + throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId()); } AccountVO account = _accountDao.findById(template.getAccountId()); - VMTemplateHostVO srcTmpltHost = _tmpltHostDao.findByHostTemplate(srcSecHost.getId(), tmpltId); + // find the size of the template to be copied + TemplateDataStoreVO srcTmpltStore = this._tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId); _resourceLimitMgr.checkResourceLimit(account, ResourceType.template); - _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltHost.getSize())); + _resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize())); // Event details String copyEventType; @@ -924,30 +941,31 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Transaction txn = Transaction.currentTxn(); txn.start(); - for ( HostVO dstSecHost : dstSecHosts ) { - VMTemplateHostVO dstTmpltHost = null; + //Copy will just find one eligible image store for the destination zone and copy template there, not propagate to all image stores + // for that zone + for ( DataStore dstSecStore : dstSecStores ) { + TemplateDataStoreVO dstTmpltStore = null; try { - dstTmpltHost = _tmpltHostDao.findByHostTemplate(dstSecHost.getId(), tmpltId, true); - if (dstTmpltHost != null) { - dstTmpltHost = _tmpltHostDao.lockRow(dstTmpltHost.getId(), true); - if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOADED) { - if (dstTmpltHost.getDestroyed() == false) { - return true; + dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId, true); + if (dstTmpltStore != null) { + dstTmpltStore = _tmplStoreDao.lockRow(dstTmpltStore.getId(), true); + if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) { + if (dstTmpltStore.getDestroyed() == false) { + return true; // already downloaded on this image store } else { - dstTmpltHost.setDestroyed(false); - _tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost); - + dstTmpltStore.setDestroyed(false); + _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); return true; } - } else if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOAD_ERROR){ - if (dstTmpltHost.getDestroyed() == true) { - dstTmpltHost.setDestroyed(false); - dstTmpltHost.setDownloadState(Status.NOT_DOWNLOADED); - dstTmpltHost.setDownloadPercent(0); - dstTmpltHost.setCopy(true); - dstTmpltHost.setErrorString(""); - dstTmpltHost.setJobId(null); - _tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost); + } else if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOAD_ERROR){ + if (dstTmpltStore.getDestroyed() == true) { + dstTmpltStore.setDestroyed(false); + dstTmpltStore.setDownloadState(Status.NOT_DOWNLOADED); + dstTmpltStore.setDownloadPercent(0); + dstTmpltStore.setCopy(true); + dstTmpltStore.setErrorString(""); + dstTmpltStore.setJobId(null); + _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); } } } @@ -955,11 +973,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, txn.commit(); } - if(_downloadMonitor.copyTemplate(template, srcSecHost, dstSecHost) ) { + if(_downloadMonitor.copyTemplate(template, srcSecStore, dstSecStore) ) { _tmpltDao.addTemplateToZone(template, dstZoneId); if(account.getId() != Account.ACCOUNT_ID_SYSTEM){ - UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(), + UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltStore.getSize(), template.getClass().getName(), template.getUuid()); } return true; @@ -969,6 +987,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } + + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true) public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException { @@ -978,6 +998,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Long destZoneId = cmd.getDestinationZoneId(); Account caller = UserContext.current().getCaller(); + /* if (_swiftMgr.isSwiftEnabled()) { throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones"); } @@ -986,6 +1007,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException( "copytemplate API is disabled in S3 setup -- S3 templates are accessible in all zones."); } + */ //Verify parameters if (sourceZoneId == destZoneId) { @@ -1007,20 +1029,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Unable to find template with id"); } - HostVO dstSecHost = getSecondaryStorageHost(destZoneId, templateId); - if ( dstSecHost != null ) { - s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecHost.getId() + " in zone " + destZoneId + " , don't need to copy"); + DataStore dstSecStore = getImageStore(destZoneId, templateId); + if ( dstSecStore != null ) { + s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId + " , don't need to copy"); return template; } - HostVO srcSecHost = getSecondaryStorageHost(sourceZoneId, templateId); - if ( srcSecHost == null ) { + DataStore srcSecStore = getImageStore(sourceZoneId, templateId); + if ( srcSecStore == null ) { throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId ); } + if ( srcSecStore.getScope().getScopeType() == ScopeType.REGION){ + s_logger.debug("Template " + templateId + " is in region-wide secondary storage " + dstSecStore.getName() + " , don't need to copy"); + return template; + } _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - boolean success = copy(userId, template, srcSecHost, sourceZone, dstZone); + boolean success = copy(userId, template, srcSecStore, dstZone); if (success){ return template; @@ -2073,6 +2099,23 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return secondaryStorageHost.getStorageUrl(); } + // get the image store where a template in a given zone is downloaded to, just pick one is enough. + @Override + public DataStore getImageStore(long zoneId, long tmpltId) { + List stores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + if (stores == null || stores.size() == 0) { + return null; + } + for (DataStore host : stores) { + List tmpltStore = this._tmplStoreDao.listByTemplateStoreDownloadStatus( + tmpltId, host.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if ( tmpltStore != null && tmpltStore.size() > 0 ){ + return host; + } + } + return null; + } + @Override public HostVO getSecondaryStorageHost(long zoneId, long tmpltId) { List hosts = _ssvmMgr diff --git a/server/test/com/cloud/agent/MockAgentManagerImpl.java b/server/test/com/cloud/agent/MockAgentManagerImpl.java index 7e3462d8ff8..9e7e163aad9 100755 --- a/server/test/com/cloud/agent/MockAgentManagerImpl.java +++ b/server/test/com/cloud/agent/MockAgentManagerImpl.java @@ -21,6 +21,7 @@ import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; @@ -140,6 +141,19 @@ public class MockAgentManagerImpl extends ManagerBase implements AgentManager { return null; } + + @Override + public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException { + // TODO Auto-generated method stub + + } + + @Override + public Answer sendToSecStorage(DataStore ssStore, Command cmd) { + // TODO Auto-generated method stub + return null; + } + @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub @@ -191,7 +205,7 @@ public class MockAgentManagerImpl extends ManagerBase implements AgentManager { @Override public void disconnectWithInvestigation(long hostId, Event event) { // TODO Auto-generated method stub - + } } From c74969fcb0ff34331a8e4c0edb3d093052219658 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 16 Apr 2013 16:53:13 -0700 Subject: [PATCH 028/303] add deleteTemplate implementation into S3 and Swift driver implementation. --- .../driver/S3ImageStoreDriverImpl.java | 73 ++++++++++++++++++- .../driver/SwiftImageStoreDriverImpl.java | 73 ++++++++++++++++++- .../cloud/template/TemplateManagerImpl.java | 26 +------ 3 files changed, 145 insertions(+), 27 deletions(-) diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 5f33a492027..10734673e4e 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -33,10 +33,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -46,10 +47,13 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; @@ -68,9 +72,14 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; public class S3ImageStoreDriverImpl implements ImageStoreDriver { private static final Logger s_logger = Logger @@ -94,6 +103,14 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject AccountDao _accountDao; + @Inject UserVmDao _userVmDao; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + private AgentManager _agentMgr; + @Inject TemplateDataStoreDao _templateStoreDao; + @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -197,7 +214,61 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + TemplateObject templateObj = (TemplateObject) data; + VMTemplateVO template = templateObj.getImage(); + ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); + long storeId = store.getId(); + Long sZoneId = store.getDataCenterId(); + long templateId = template.getId(); + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + String eventType = ""; + + if (template.getFormat().equals(ImageFormat.ISO)) { + eventType = EventTypes.EVENT_ISO_DELETE; + } else { + eventType = EventTypes.EVENT_TEMPLATE_DELETE; + } + + // TODO: need to understand why we need to mark destroyed in + // template_store_ref table here instead of in callback. + // Currently I did that in callback, so I removed previous code to mark template_host_ref + + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + // check if there is any VM using this ISO. + if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); + + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSucess(false); + callback.complete(result); + } + + // for S3, a template can be associated with multiple zones + List templateZones = templateZoneDao + .listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } + } + } } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index e96bfffa6a2..88405d284ba 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -33,10 +33,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -46,10 +47,13 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; @@ -68,9 +72,14 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; public class SwiftImageStoreDriverImpl implements ImageStoreDriver { private static final Logger s_logger = Logger @@ -94,6 +103,14 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject AccountDao _accountDao; + @Inject UserVmDao _userVmDao; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + private AgentManager _agentMgr; + @Inject TemplateDataStoreDao _templateStoreDao; + @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -190,7 +207,61 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + TemplateObject templateObj = (TemplateObject) data; + VMTemplateVO template = templateObj.getImage(); + ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); + long storeId = store.getId(); + Long sZoneId = store.getDataCenterId(); + long templateId = template.getId(); + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + String eventType = ""; + + if (template.getFormat().equals(ImageFormat.ISO)) { + eventType = EventTypes.EVENT_ISO_DELETE; + } else { + eventType = EventTypes.EVENT_TEMPLATE_DELETE; + } + + // TODO: need to understand why we need to mark destroyed in + // template_store_ref table here instead of in callback. + // Currently I did that in callback, so I removed previous code to mark template_host_ref + + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + // check if there is any VM using this ISO. + if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); + + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSucess(false); + callback.complete(result); + } + + // for Swift, a template can be associated with multiple zones + List templateZones = templateZoneDao + .listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } + } + } } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index e9729e4ff31..da0b884ecd5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1487,34 +1487,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template.getFormat() == ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid template."); } - /* - if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) { - _swiftMgr.deleteTemplate(cmd); - } - if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) { - _s3Mgr.deleteTemplate(cmd.getId(), caller.getAccountId()); - } - */ TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); - boolean result = adapter.delete(profile); - - if (result){ - if (cmd.getZoneId() == null - && (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) { - List templateZones = _tmpltZoneDao - .listByZoneTemplate(null, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - _tmpltZoneDao.remove(templateZone.getId()); - } - } - } - return true; - }else{ - throw new CloudRuntimeException("Failed to delete template"); - } + return adapter.delete(profile); } @Override From fe3b01ece1efd193ecc74dc31b1f6a469a7b451c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 17 Apr 2013 11:40:57 -0700 Subject: [PATCH 029/303] Update DataObjectInStore interface and unify implementation of ImageDataFactory, VolumeDataFactory and SnapshotDataFactory implementations. --- .../com/cloud/storage/VMTemplateHostVO.java | 73 ++++++----- .../storage/VMTemplateStoragePoolVO.java | 58 +++++---- core/src/com/cloud/storage/VolumeHostVO.java | 119 ++++++++++-------- .../api/storage/DataObjectInStore.java | 2 + .../datastore/db/SnapshotDataStoreDao.java | 8 ++ .../datastore/db/SnapshotDataStoreVO.java | 7 ++ .../datastore/db/TemplateDataStoreVO.java | 8 ++ .../datastore/db/VolumeDataStoreDao.java | 6 +- .../datastore/db/VolumeDataStoreVO.java | 7 ++ .../storage/image/ImageDataFactoryImpl.java | 14 +-- .../snapshot/SnapshotDataFactoryImpl.java | 18 +-- .../ObjectInDataStoreManagerImpl.java | 31 ++--- .../storage/db/ObjectInDataStoreVO.java | 48 +++---- .../image/db/SnapshotDataStoreDaoImpl.java | 50 ++++++++ .../image/db/VolumeDataStoreDaoImpl.java | 21 +++- .../storage/volume/VolumeDataFactoryImpl.java | 18 +-- .../storage/volume/VolumeServiceImpl.java | 2 +- 17 files changed, 313 insertions(+), 177 deletions(-) diff --git a/core/src/com/cloud/storage/VMTemplateHostVO.java b/core/src/com/cloud/storage/VMTemplateHostVO.java index b8dfc41d51b..8b257598041 100755 --- a/core/src/com/cloud/storage/VMTemplateHostVO.java +++ b/core/src/com/cloud/storage/VMTemplateHostVO.java @@ -44,66 +44,66 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj @Id @GeneratedValue(strategy=GenerationType.IDENTITY) Long id; - + @Column(name="host_id") private long hostId; - + @Column(name="template_id") private long templateId; - + @Column(name=GenericDaoBase.CREATED_COLUMN) private Date created = null; - + @Column(name="last_updated") @Temporal(value=TemporalType.TIMESTAMP) private Date lastUpdated = null; - + @Column (name="download_pct") private int downloadPercent; - + @Column (name="size") private long size; - + @Column (name="physical_size") private long physicalSize; - + @Column (name="download_state") @Enumerated(EnumType.STRING) private Status downloadState; - + @Column (name="local_path") private String localDownloadPath; - + @Column (name="error_str") private String errorString; - + @Column (name="job_id") - private String jobId; - + private String jobId; + @Column (name="install_path") private String installPath; - + @Column (name="url") private String downloadUrl; @Column(name="is_copy") private boolean isCopy = false; - + @Column(name="destroyed") boolean destroyed = false; - + @Column(name="update_count", updatable = true, nullable=false) protected long updatedCount; - + @Column(name = "updated") @Temporal(value = TemporalType.TIMESTAMP) Date updated; - + @Column(name = "state") @Enumerated(EnumType.STRING) ObjectInDataStoreStateMachine.State state; - - + + @Override public String getInstallPath() { return installPath; @@ -156,12 +156,12 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj public Date getLastUpdated() { return lastUpdated; } - + @Override public void setLastUpdated(Date date) { lastUpdated = date; } - + @Override public void setInstallPath(String installPath) { this.installPath = installPath; @@ -197,7 +197,7 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj } protected VMTemplateHostVO() { - + } @Override @@ -234,7 +234,7 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj public boolean equals(Object obj) { if (obj instanceof VMTemplateHostVO) { VMTemplateHostVO other = (VMTemplateHostVO)obj; - return (this.templateId==other.getTemplateId() && this.hostId==other.getHostId()); + return (this.templateId==other.getTemplateId() && this.hostId==other.getHostId()); } return false; } @@ -253,8 +253,8 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj public long getSize() { return size; } - - + + public void setPhysicalSize(long physicalSize) { this.physicalSize = physicalSize; } @@ -286,12 +286,12 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj public boolean isCopy() { return isCopy; } - + @Override public long getTemplateSize() { return -1; } - + @Override public String toString() { return new StringBuilder("TmplHost[").append(id).append("-").append(templateId).append("-").append(hostId).append(installPath).append("]").toString(); @@ -302,11 +302,11 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj // TODO Auto-generated method stub return this.state; } - + public long getUpdatedCount() { return this.updatedCount; } - + public void incrUpdatedCount() { this.updatedCount++; } @@ -314,9 +314,20 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj public void decrUpdatedCount() { this.updatedCount--; } - + public Date getUpdated() { return updated; } + @Override + public long getObjectId() { + return this.getTemplateId(); + } + + @Override + public long getDataStoreId() { + return this.getHostId(); + } + + } diff --git a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java index 9b761764359..638ddd090a6 100644 --- a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java +++ b/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java @@ -45,32 +45,32 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, @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="update_count", updatable = true, nullable=false) @@ -88,7 +88,7 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, public String getInstallPath() { return installPath; } - + @Override public long getTemplateSize() { return templateSize; @@ -141,12 +141,12 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, public Date getLastUpdated() { return lastUpdated; } - + @Override public void setLastUpdated(Date date) { lastUpdated = date; } - + @Override public void setInstallPath(String installPath) { this.installPath = installPath; @@ -184,7 +184,7 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, } protected VMTemplateStoragePoolVO() { - + } @Override @@ -216,15 +216,15 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, 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; } @@ -244,7 +244,7 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, 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(); @@ -254,11 +254,11 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, public State getState() { return this.state; } - + public long getUpdatedCount() { return this.updatedCount; } - + public void incrUpdatedCount() { this.updatedCount++; } @@ -266,10 +266,20 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, public void decrUpdatedCount() { this.updatedCount--; } - + public Date getUpdated() { return updated; } - + + @Override + public long getObjectId() { + return this.getTemplateId(); + } + + @Override + public long getDataStoreId() { + return this.getPoolId(); + } + } diff --git a/core/src/com/cloud/storage/VolumeHostVO.java b/core/src/com/cloud/storage/VolumeHostVO.java index 40bae499122..63b1091059e 100755 --- a/core/src/com/cloud/storage/VolumeHostVO.java +++ b/core/src/com/cloud/storage/VolumeHostVO.java @@ -47,71 +47,71 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) Long id; - + @Column(name="host_id") private long hostId; - + @Column(name="volume_id") private long volumeId; - + @Column(name="zone_id") private long zoneId; - + @Column(name=GenericDaoBase.CREATED_COLUMN) private Date created = null; - + @Column(name="last_updated") @Temporal(value=TemporalType.TIMESTAMP) private Date lastUpdated = null; - + @Column (name="download_pct") private int downloadPercent; - + @Column (name="size") private long size; - + @Column (name="physical_size") private long physicalSize; - + @Column (name="download_state") @Enumerated(EnumType.STRING) private Status downloadState; - + @Column(name="checksum") private String checksum; - + @Column (name="local_path") private String localDownloadPath; - + @Column (name="error_str") private String errorString; - + @Column (name="job_id") - private String jobId; - + private String jobId; + @Column (name="install_path") private String installPath; - + @Column (name="url") private String downloadUrl; - + @Column(name="format") private Storage.ImageFormat format; - + @Column(name="destroyed") boolean destroyed = false; - + @Column(name="update_count", updatable = true, nullable=false) protected long updatedCount; - + @Column(name = "updated") @Temporal(value = TemporalType.TIMESTAMP) Date updated; - + @Column(name = "state") @Enumerated(EnumType.STRING) ObjectInDataStoreStateMachine.State state; - + public String getInstallPath() { return installPath; } @@ -124,17 +124,17 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { this.hostId = hostId; } - + public long getVolumeId() { return volumeId; } - + public void setVolumeId(long volumeId) { this.volumeId = volumeId; } - + public long getZoneId() { return zoneId; } @@ -147,42 +147,42 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { 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; } @@ -223,49 +223,49 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { } protected VolumeHostVO() { - + } - + 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 boolean equals(Object obj) { if (obj instanceof VolumeHostVO) { VolumeHostVO other = (VolumeHostVO)obj; - return (this.volumeId==other.getVolumeId() && this.hostId==other.getHostId()); + return (this.volumeId==other.getVolumeId() && this.hostId==other.getHostId()); } return false; } - + public int hashCode() { Long tid = new Long(volumeId); Long hid = new Long(hostId); @@ -279,8 +279,8 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { public long getSize() { return size; } - - + + public void setPhysicalSize(long physicalSize) { this.physicalSize = physicalSize; } @@ -303,8 +303,8 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { public String getDownloadUrl() { return downloadUrl; - } - + } + public Storage.ImageFormat getFormat() { return format; } @@ -316,16 +316,16 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { public long getVolumeSize() { return -1; } - - + + public String toString() { return new StringBuilder("VolumeHost[").append(id).append("-").append(volumeId).append("-").append(hostId).append(installPath).append("]").toString(); } - + public long getUpdatedCount() { return this.updatedCount; } - + public void incrUpdatedCount() { this.updatedCount++; } @@ -333,7 +333,7 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { public void decrUpdatedCount() { this.updatedCount--; } - + public Date getUpdated() { return updated; } @@ -344,4 +344,15 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { return this.state; } + @Override + public long getObjectId() { + return this.getVolumeId(); + } + + @Override + public long getDataStoreId() { + return this.getHostId(); + } + + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java index 32ea996e638..ded2640bb82 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java @@ -24,4 +24,6 @@ import com.cloud.utils.fsm.StateObject; public interface DataObjectInStore extends StateObject { public String getInstallPath(); public void setInstallPath(String path); + public long getObjectId(); + public long getDataStoreId(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index 271ff41f08e..b4e5022c90d 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -31,4 +31,12 @@ public interface SnapshotDataStoreDao extends GenericDao listByStoreId(long id); public void deletePrimaryRecordsForStore(long id); + + public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId); + + public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId, boolean lock); + + public SnapshotDataStoreVO findBySnapshot(long snapshotId); + + public List listDestroyed(long storeId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index c257fb5c39c..e4c4942862f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -95,6 +95,7 @@ public class SnapshotDataStoreVO implements StateObject, public void deletePrimaryRecordsForStore(long id); - public VolumeDataStoreVO findByVolumeId(long volumeId); + public VolumeDataStoreVO findByVolume(long volumeId); public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId); + + public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId, boolean lock); + + public List listDestroyed(long storeId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index a7134ea374c..d589b5c8b1d 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -117,6 +117,7 @@ public class VolumeDataStoreVO implements StateObject ts = templateDataStoreDao.createSearchCriteria(); - ts.addAnd("templateId", SearchCriteria.Op.EQ, objId); - ts.addAnd("dataStoreId", SearchCriteria.Op.EQ, dataStoreId); - vo = templateDataStoreDao.findOneBy(ts); + vo = templateDataStoreDao.findByStoreTemplate(dataStoreId, objId); case SNAPSHOT: - SearchCriteria ss = snapshotDataStoreDao.createSearchCriteria(); - ss.addAnd("snapshotId", SearchCriteria.Op.EQ, objId); - ss.addAnd("dataStoreId", SearchCriteria.Op.EQ, objId); - vo = snapshotDataStoreDao.findOneBy(ss); + vo = snapshotDataStoreDao.findByStoreSnapshot(dataStoreId, objId); case VOLUME: - SearchCriteria vs = volumeDataStoreDao.createSearchCriteria(); - vs.addAnd("volumeId", SearchCriteria.Op.EQ, objId); - vs.addAnd("dataStoreId", SearchCriteria.Op.EQ, objId); - vo = volumeDataStoreDao.findOneBy(vs); + vo = volumeDataStoreDao.findByStoreVolume(dataStoreId, objId); } } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); @@ -255,13 +246,17 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { public DataStore findStore(long objId, DataObjectType type, DataStoreRole role) { DataStore store = null; if (role == DataStoreRole.Image) { - SearchCriteriaService sc = SearchCriteria2.create(ObjectInDataStoreVO.class); - sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role); - sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId); - sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type); - ObjectInDataStoreVO vo = sc.find(); + DataObjectInStore vo = null; + switch (type){ + case TEMPLATE: + vo = templateDataStoreDao.findByTemplate(objId); + case SNAPSHOT: + vo = snapshotDataStoreDao.findBySnapshot(objId); + case VOLUME: + vo = volumeDataStoreDao.findByVolume(objId); + } if (vo != null) { - store = this.storeMgr.getDataStore(vo.getDataStoreId(), vo.getDataStoreRole()); + store = this.storeMgr.getDataStore(vo.getDataStoreId(), DataStoreRole.Image); } } return store; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index fb8c93ceedc..44b91745d61 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -48,14 +48,14 @@ public class ObjectInDataStoreVO implements StateObject updateStateSearch; private SearchBuilder storeSearch; + private SearchBuilder snapshotSearch; + private SearchBuilder storeSnapshotSearch; @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -57,6 +60,18 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = storeSnapshotSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("snapshot_id", snapshotId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + @Override + public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId, boolean lock) { + SearchCriteria sc = storeSnapshotSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("snapshot_id", snapshotId); + sc.setParameters("destroyed", false); + if (!lock) + return findOneIncludingRemovedBy(sc); + else + return lockOneRandomRow(sc, true); + } + + @Override + public SnapshotDataStoreVO findBySnapshot(long snapshotId) { + SearchCriteria sc = snapshotSearch.create(); + sc.setParameters("snapshot_id", snapshotId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + + @Override + public List listDestroyed(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", true); + return listIncludingRemovedBy(sc); + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index dc6c2354952..c144b360cb1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -133,12 +133,13 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase sc = volumeSearch.create(); sc.setParameters("volume_id", volumeId); sc.setParameters("destroyed", false); return findOneBy(sc); } + @Override public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId) { SearchCriteria sc = storeVolumeSearch.create(); @@ -148,5 +149,23 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase sc = storeVolumeSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("volume_id", volumeId); + sc.setParameters("destroyed", false); + if (!lock) + return findOneIncludingRemovedBy(sc); + else + return lockOneRandomRow(sc, true); + } + @Override + public List listDestroyed(long id) { + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("destroyed", true); + return listIncludingRemovedBy(sc); + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java index 2929d3881e5..e7a42dea750 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java @@ -21,12 +21,12 @@ package org.apache.cloudstack.storage.volume; import javax.inject.Inject; 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; @@ -38,24 +38,28 @@ public class VolumeDataFactoryImpl implements VolumeDataFactory { @Inject VolumeDao volumeDao; @Inject - ObjectInDataStoreManager objMap; + VolumeDataStoreDao volumeStoreDao; @Inject DataStoreManager storeMgr; @Override public VolumeInfo getVolume(long volumeId, DataStore store) { VolumeVO volumeVO = volumeDao.findById(volumeId); - + VolumeObject vol = VolumeObject.getVolumeObject(store, volumeVO); - + return vol; } - + @Override public VolumeInfo getVolume(long volumeId) { VolumeVO volumeVO = volumeDao.findById(volumeId); VolumeObject vol = null; if (volumeVO.getPoolId() == null) { - DataStore store = objMap.findStore(volumeVO.getId(), DataObjectType.VOLUME, DataStoreRole.Image); + DataStore store = null; + VolumeDataStoreVO volumeStore = volumeStoreDao.findByVolume(volumeId); + if ( volumeStore != null ){ + store = this.storeMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); + } vol = VolumeObject.getVolumeObject(store, volumeVO); } else { DataStore store = this.storeMgr.getDataStore(volumeVO.getPoolId(), DataStoreRole.Primary); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 22320957e63..d4087ed66f3 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -774,7 +774,7 @@ public class VolumeServiceImpl implements VolumeService { if (volInfo.getSize() > 0) { try { - String url = _volumeStoreDao.findByVolumeId(volume.getId()).getDownloadUrl(); + String url = _volumeStoreDao.findByVolume(volume.getId()).getDownloadUrl(); _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() - UriUtils.getRemoteSize(url)); From 14b5f0da198b4acae79f1ef438b27250ee60b8f2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 17 Apr 2013 11:45:25 -0700 Subject: [PATCH 030/303] Rename ImageDataFactoryxxx to TemplateDataFactory to have consistent naming conventions for Template data factory class. --- .../{ImageDataFactory.java => TemplateDataFactory.java} | 2 +- ...ageDataFactoryImpl.java => TemplateDataFactoryImpl.java} | 6 +++--- .../apache/cloudstack/storage/test/volumeServiceTest.java | 4 ++-- .../storage/datastore/ObjectInDataStoreManagerImpl.java | 4 ++-- .../cloudstack/storage/datastore/PrimaryDataStoreImpl.java | 4 ++-- .../storage/volume/TemplateInstallStrategyImpl.java | 4 ++-- server/src/com/cloud/storage/StorageManagerImpl.java | 4 ++-- server/src/com/cloud/storage/VolumeManagerImpl.java | 4 ++-- .../src/com/cloud/template/HypervisorTemplateAdapter.java | 4 ++-- server/src/com/cloud/template/TemplateManagerImpl.java | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) rename engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/{ImageDataFactory.java => TemplateDataFactory.java} (96%) rename engine/storage/image/src/org/apache/cloudstack/storage/image/{ImageDataFactoryImpl.java => TemplateDataFactoryImpl.java} (95%) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java similarity index 96% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataFactory.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java index f0d69887c7d..c2775a351e8 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java @@ -19,7 +19,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; -public interface ImageDataFactory { +public interface TemplateDataFactory { TemplateInfo getTemplate(long templateId, DataStore store); TemplateInfo getTemplate(DataObject obj, DataStore store); TemplateInfo getTemplate(long templateId); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java similarity index 95% rename from engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java rename to engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java index 2c091cc0372..2f65b6bbd50 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java @@ -23,7 +23,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; 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; @@ -38,9 +38,9 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; @Component -public class ImageDataFactoryImpl implements ImageDataFactory { +public class TemplateDataFactoryImpl implements TemplateDataFactory { private static final Logger s_logger = Logger - .getLogger(ImageDataFactoryImpl.class); + .getLogger(TemplateDataFactoryImpl.class); @Inject VMTemplateDao imageDataDao; @Inject diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 64d2143ba8c..f8aacc0d0ef 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -38,7 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; @@ -110,7 +110,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { @Inject EndPointSelector selector; @Inject - ImageDataFactory imageDataFactory; + TemplateDataFactory imageDataFactory; @Inject VolumeDataFactory volumeFactory; Long dcId; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 6e1267887cc..89d61605de0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -23,7 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -58,7 +58,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { private static final Logger s_logger = Logger .getLogger(ObjectInDataStoreManagerImpl.class); @Inject - ImageDataFactory imageFactory; + TemplateDataFactory imageFactory; @Inject DataStoreManager storeMgr; @Inject diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 8be1c8a7e47..4c214c1b72a 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -29,7 +29,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; @@ -72,7 +72,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Inject private ObjectInDataStoreManager objectInStoreMgr; @Inject - ImageDataFactory imageDataFactory; + TemplateDataFactory imageDataFactory; @Inject SnapshotDataFactory snapshotFactory; protected DataStoreProvider provider; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java index 69979e5a16a..b57d99dc1c6 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java @@ -21,7 +21,7 @@ package org.apache.cloudstack.storage.volume; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; @@ -39,7 +39,7 @@ public class TemplateInstallStrategyImpl implements TemplateInstallStrategy { @Inject DataMotionService motionSrv; @Inject - ImageDataFactory imageFactory; + TemplateDataFactory imageFactory; protected long waitingTime = 1800; // half an hour protected long waitingRetries = 10; /* diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index d46b2c61369..fb3d3207ad3 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -55,7 +55,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -313,7 +313,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject VolumeDataFactory volFactory; @Inject - ImageDataFactory tmplFactory; + TemplateDataFactory tmplFactory; @Inject SnapshotDataFactory snapshotFactory; @Inject diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 4b870800355..4a7a1409ae6 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -45,7 +45,7 @@ import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; 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.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -305,7 +305,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @Inject VolumeDataFactory volFactory; @Inject - ImageDataFactory tmplFactory; + TemplateDataFactory tmplFactory; @Inject SnapshotDataFactory snapshotFactory; private int _copyvolumewait; diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 3399ca1e92d..8906eaf9c62 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -34,7 +34,7 @@ import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; @@ -77,7 +77,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te @Inject DataStoreManager storeMgr; @Inject TemplateService imageService; - @Inject ImageDataFactory imageFactory; + @Inject TemplateDataFactory imageFactory; @Inject TemplateManager templateMgr; @Override diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index da0b884ecd5..7ef658c76e2 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -56,7 +56,7 @@ import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissions import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.ImageDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -248,7 +248,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject VolumeDataFactory volFactory; @Inject - ImageDataFactory tmplFactory; + TemplateDataFactory tmplFactory; @Inject SnapshotDataFactory snapshotFactory; @Inject From fe4f53bfcdbe157e9500e2a806f7f9942250211e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 17 Apr 2013 17:16:01 -0700 Subject: [PATCH 031/303] Fix SecStorageSetupCommand for Nfs image store. --- .../agent/api/SecStorageSetupCommand.java | 15 ++++++- .../resource/NfsSecondaryStorageResource.java | 43 +++++++++++-------- .../storage/datastore/db/ImageStoreVO.java | 15 ++++++- .../storage/image/store/ImageStoreImpl.java | 3 ++ .../storage/download/DownloadMonitorImpl.java | 10 +++-- .../SecondaryStorageManagerImpl.java | 35 ++++++++++----- .../cloud/template/TemplateManagerImpl.java | 6 +-- .../cloud/upgrade/dao/Upgrade410to420.java | 18 ++++---- setup/db/db/schema-410to420.sql | 1 + 9 files changed, 102 insertions(+), 44 deletions(-) diff --git a/api/src/com/cloud/agent/api/SecStorageSetupCommand.java b/api/src/com/cloud/agent/api/SecStorageSetupCommand.java index 50c06cffa43..b1f32348baa 100644 --- a/api/src/com/cloud/agent/api/SecStorageSetupCommand.java +++ b/api/src/com/cloud/agent/api/SecStorageSetupCommand.java @@ -17,8 +17,10 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; +import com.cloud.agent.api.to.DataStoreTO; public class SecStorageSetupCommand extends Command { + private DataStoreTO store; private String secUrl; private Certificates certs; @@ -57,10 +59,11 @@ public class SecStorageSetupCommand extends Command { super(); } - public SecStorageSetupCommand(String secUrl, Certificates certs) { + public SecStorageSetupCommand(DataStoreTO store, String secUrl, Certificates certs) { super(); this.secUrl = secUrl; this.certs = certs; + this.store = store; } @Override @@ -80,4 +83,14 @@ public class SecStorageSetupCommand extends Command { this.secUrl = secUrl; } + + public DataStoreTO getDataStore() { + return store; + } + + public void setDataStore(DataStoreTO store) { + this.store = store; + } + + } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index bb5b454f932..04b715d5268 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -968,29 +968,36 @@ SecondaryStorageResource { if (!_inSystemVM){ return new Answer(cmd, true, null); } - String secUrl = cmd.getSecUrl(); - try { - URI uri = new URI(secUrl); - String nfsHost = uri.getHost(); + DataStoreTO dStore = cmd.getDataStore(); + if (dStore instanceof NfsTO ){ + String secUrl = cmd.getSecUrl(); + try { + URI uri = new URI(secUrl); + String nfsHost = uri.getHost(); - InetAddress nfsHostAddr = InetAddress.getByName(nfsHost); - String nfsHostIp = nfsHostAddr.getHostAddress(); + InetAddress nfsHostAddr = InetAddress.getByName(nfsHost); + String nfsHostIp = nfsHostAddr.getHostAddress(); - addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp); - String nfsPath = nfsHostIp + ":" + uri.getPath(); - String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString(); - String root = _parent + "/" + dir; - mount(root, nfsPath); + addRouteToInternalIpOrCidr(_storageGateway, _storageIp, _storageNetmask, nfsHostIp); + String nfsPath = nfsHostIp + ":" + uri.getPath(); + String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString(); + String root = _parent + "/" + dir; + mount(root, nfsPath); - configCerts(cmd.getCerts()); + configCerts(cmd.getCerts()); - nfsIps.add(nfsHostIp); - return new SecStorageSetupAnswer(dir); - } catch (Exception e) { - String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); - s_logger.error(msg); - return new Answer(cmd, false, msg); + nfsIps.add(nfsHostIp); + return new SecStorageSetupAnswer(dir); + } catch (Exception e) { + String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); + s_logger.error(msg); + return new Answer(cmd, false, msg); + } + } + else{ + // TODO: what do we need to setup for S3/Swift, maybe need to mount to some cache storage + return new Answer(cmd, true, null); } } 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 39b74d00e77..676004b0314 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 @@ -71,11 +71,16 @@ public class ImageStoreVO implements ImageStore { @Column(name=GenericDao.REMOVED_COLUMN) private Date removed; - + @Column(name = "role") @Enumerated(value = EnumType.STRING) private DataStoreRole role; + @Column(name="parent") + private String parent; + + + public DataStoreRole getRole() { return role; } @@ -160,6 +165,14 @@ public class ImageStoreVO implements ImageStore { this.removed = removed; } + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index bc8d2e2a10f..638e1351947 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -178,5 +178,8 @@ public class ImageStoreImpl implements ImageStoreEntity { return getDriver().getStoreTO(this); } + public ImageStoreVO getImageStoreVO(){ + return this.imageDataStoreVO; + } } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 50ded27e349..6af8db5d4c9 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -30,6 +30,8 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; @@ -126,6 +128,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject SecondaryStorageVmDao _secStorageVmDao; @Inject + ImageStoreDao _imageStoreDao; + @Inject VolumeDao _volumeDao; @Inject VolumeHostDao _volumeHostDao; @@ -344,9 +348,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor s_logger.warn("A running secondary storage vm has a null public ip?"); return null; } - //TODO: how to handle parent field from hostVO in image_store? and how we can populate that column? - // return generateCopyUrl(ssVm.getPublicIpAddress(), sourceServer.getParent(), srcTmpltStore.getInstallPath()); - return generateCopyUrl(ssVm.getPublicIpAddress(), null, srcTmpltStore.getInstallPath()); + // get parent path of nfs secondary storage + ImageStoreVO svo = this._imageStoreDao.findById(sourceServer.getId()); + return generateCopyUrl(ssVm.getPublicIpAddress(), svo.getParent(), srcTmpltStore.getInstallPath()); } VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId()); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 7a1984cda4e..1b50083abc5 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -30,7 +30,11 @@ 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.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.log4j.Logger; import org.springframework.context.annotation.Primary; import org.springframework.stereotype.Component; @@ -240,6 +244,10 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar @Inject KeystoreManager _keystoreMgr; + @Inject + DataStoreManager _dataStoreMgr; + @Inject + ImageStoreDao _imageStoreDao; private long _capacityScanInterval = DEFAULT_CAPACITY_SCAN_INTERVAL; private int _secStorageVmMtuSize; @@ -300,33 +308,39 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar return false; } - List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId); - for( HostVO ssHost : ssHosts ) { - String secUrl = ssHost.getStorageUrl(); + List ssStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + for( DataStore ssStore : ssStores ) { + String secUrl = ssStore.getUri(); SecStorageSetupCommand setupCmd = null; if (!_useSSlCopy) { - setupCmd = new SecStorageSetupCommand(secUrl, null); + setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, null); } else { Certificates certs = _keystoreMgr.getCertificates(ConsoleProxyManager.CERTIFICATE_NAME); - setupCmd = new SecStorageSetupCommand(secUrl, certs); + setupCmd = new SecStorageSetupCommand(ssStore.getTO(), secUrl, certs); } Answer answer = _agentMgr.easySend(ssHostId, setupCmd); if (answer != null && answer.getResult()) { SecStorageSetupAnswer an = (SecStorageSetupAnswer) answer; - ssHost.setParent(an.get_dir()); - _hostDao.update(ssHost.getId(), ssHost); + if (an.get_dir() != null){ + // update the parent path in image_store table for this image store + ImageStoreVO svo = this._imageStoreDao.findById(ssStore.getId()); + svo.setParent(an.get_dir()); + _imageStoreDao.update(ssStore.getId(), svo); + } if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully programmed secondary storage " + ssHost.getName() + " in secondary storage VM " + secStorageVm.getInstanceName()); + s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName()); } } else { if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully programmed secondary storage " + ssHost.getName() + " in secondary storage VM " + secStorageVm.getInstanceName()); + s_logger.debug("Successfully programmed secondary storage " + ssStore.getName() + " in secondary storage VM " + secStorageVm.getInstanceName()); } return false; } } - } else if( cssHost.getType() == Host.Type.SecondaryStorage ) { + } + /* After removing SecondaryStorage entries from host table, control should never come here!! + else if( cssHost.getType() == Host.Type.SecondaryStorage ) { List alreadyRunning = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, zoneId, State.Running); String secUrl = cssHost.getStorageUrl(); SecStorageSetupCommand setupCmd = new SecStorageSetupCommand(secUrl, null); @@ -345,6 +359,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } } } + */ return true; } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 7ef658c76e2..6640df208a5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -252,7 +252,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject SnapshotDataFactory snapshotFactory; @Inject - TemplateService imageSvr; + TemplateService tmpltSvr; @Inject DataStoreManager dataStoreMgr; @Inject @@ -1768,11 +1768,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, AsyncCallFuture future = null; if (snapshotId != null) { SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId); - future = this.imageSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); + future = this.tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); } else if (volumeId != null) { volume = _volumeDao.findById(volumeId); VolumeInfo volInfo = this.volFactory.getVolume(volumeId); - future = this.imageSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0)); + future = this.tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0)); } else { throw new CloudRuntimeException( "Creating private Template need to specify snapshotId or volumeId"); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java b/server/src/com/cloud/upgrade/dao/Upgrade410to420.java index f39038fea8a..a39d5bc527d 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -66,8 +66,9 @@ public class Upgrade410to420 implements DbUpgrade { updateCluster_details(conn); updatePrimaryStore(conn); } - + private void updateSystemVmTemplates(Connection conn) { + /* TODO: where should be system vm templates located? PreparedStatement sql = null; try { sql = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'"); @@ -82,8 +83,9 @@ public class Upgrade410to420 implements DbUpgrade { } } } + */ } - + private void updatePrimaryStore(Connection conn) { PreparedStatement sql = null; PreparedStatement sql2 = null; @@ -92,7 +94,7 @@ public class Upgrade410to420 implements DbUpgrade { sql.setString(1, "ancient primary data store provider"); sql.setString(2, "HOST"); sql.executeUpdate(); - + sql2 = conn.prepareStatement("update storage_pool set storage_provider_name = ? , scope = ? where pool_type != 'Filesystem' and pool_type != 'LVM'"); sql2.setString(1, "ancient primary data store provider"); sql2.setString(2, "CLUSTER"); @@ -106,7 +108,7 @@ public class Upgrade410to420 implements DbUpgrade { } catch (SQLException e) { } } - + if (sql2 != null) { try { sql2.close(); @@ -234,7 +236,7 @@ public class Upgrade410to420 implements DbUpgrade { } } } - + private void createPlaceHolderNics(Connection conn) { PreparedStatement pstmt = null; ResultSet rs = null; @@ -255,7 +257,7 @@ public class Upgrade410to420 implements DbUpgrade { pstmt.setLong(4, networkId); pstmt.executeUpdate(); s_logger.debug("Created placeholder nic for the ipAddress " + ip); - + } } catch (SQLException e) { throw new CloudRuntimeException("Unable to create placeholder nics", e); @@ -271,8 +273,8 @@ public class Upgrade410to420 implements DbUpgrade { } } } - - + + private void updateRemoteAccessVpn(Connection conn) { PreparedStatement pstmt = null; ResultSet rs = null; diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 65eedee9dbb..fd030889909 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -77,6 +77,7 @@ CREATE TABLE `cloud`.`image_store` ( `data_center_id` bigint unsigned COMMENT 'datacenter id of data store', `scope` varchar(255) COMMENT 'scope of data store', `uuid` varchar(255) COMMENT 'uuid of data store', + `parent` varchar(255) COMMENT 'parent path for the storage server', `created` datetime COMMENT 'date the image store first signed on', `removed` datetime COMMENT 'date removed if not null', PRIMARY KEY(`id`) From 1a74dfaa270b86ef69beefd7bc34a836f04c9eb5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 17 Apr 2013 17:39:33 -0700 Subject: [PATCH 032/303] Move UpdateTemplate and UpdateIso methods from ManagerServerImpl to TemplateManagerImpl. --- .../com/cloud/server/ManagementService.java | 11 +-- .../cloud/template/TemplateApiService.java | 7 +- .../api/command/user/iso/UpdateIsoCmd.java | 2 +- .../user/template/UpdateTemplateCmd.java | 2 +- .../cloud/server/ManagementServerImpl.java | 92 ------------------ .../com/cloud/template/TemplateManager.java | 5 + .../cloud/template/TemplateManagerImpl.java | 96 +++++++++++++++++++ 7 files changed, 110 insertions(+), 105 deletions(-) diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 1e6ca8d0b67..d58ea3ec384 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -123,21 +123,12 @@ public interface ManagementService { /** * Searches for servers by the specified search criteria Can search by: "name", "type", "state", "dataCenterId", * "podId" - * + * * @param cmd * @return List of Hosts */ Pair, Integer> searchForServers(ListHostsCmd cmd); - /** - * Creates a new template - * - * @param cmd - * @return updated template - */ - VirtualMachineTemplate updateTemplate(UpdateIsoCmd cmd); - - VirtualMachineTemplate updateTemplate(UpdateTemplateCmd cmd); diff --git a/api/src/com/cloud/template/TemplateApiService.java b/api/src/com/cloud/template/TemplateApiService.java index 50373fef651..e3906e10d83 100755 --- a/api/src/com/cloud/template/TemplateApiService.java +++ b/api/src/com/cloud/template/TemplateApiService.java @@ -24,11 +24,13 @@ import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; +import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd; import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd; import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; +import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import com.cloud.exception.InternalErrorException; import com.cloud.exception.ResourceAllocationException; @@ -90,11 +92,14 @@ public interface TemplateApiService { List listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd); boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd); - + VirtualMachineTemplate createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException; VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) throws CloudRuntimeException; + VirtualMachineTemplate updateTemplate(UpdateIsoCmd cmd); + + VirtualMachineTemplate updateTemplate(UpdateTemplateCmd cmd); } diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java index 37294e3563a..1384fa8c573 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java @@ -66,7 +66,7 @@ public class UpdateIsoCmd extends BaseUpdateTemplateOrIsoCmd { @Override public void execute(){ - VirtualMachineTemplate result = _mgr.updateTemplate(this); + VirtualMachineTemplate result = _templateService.updateTemplate(this); if (result != null) { TemplateResponse response = _responseGenerator.createIsoResponse(result); response.setResponseName(getCommandName()); diff --git a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java index 3987dbedc3e..e342fb1c204 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java @@ -66,7 +66,7 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd { @Override public void execute(){ - VirtualMachineTemplate result = _mgr.updateTemplate(this); + VirtualMachineTemplate result = _templateService.updateTemplate(this); if (result != null) { TemplateResponse response = _responseGenerator.createIsoResponse(result); response.setObjectName("template"); diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index ee0fbdb1c52..ff60ce53fed 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1275,99 +1275,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return templateZonePairSet; } - @Override - public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) { - return updateTemplateOrIso(cmd); - } - @Override - public VMTemplateVO updateTemplate(UpdateTemplateCmd cmd) { - return updateTemplateOrIso(cmd); - } - - private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) { - Long id = cmd.getId(); - String name = cmd.getTemplateName(); - String displayText = cmd.getDisplayText(); - String format = cmd.getFormat(); - Long guestOSId = cmd.getOsTypeId(); - Boolean passwordEnabled = cmd.isPasswordEnabled(); - Boolean bootable = cmd.isBootable(); - Integer sortKey = cmd.getSortKey(); - Account account = UserContext.current().getCaller(); - - // verify that template exists - VMTemplateVO template = _templateDao.findById(id); - if (template == null || template.getRemoved() != null) { - InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id"); - ex.addProxyObject(template, id, "templateId"); - throw ex; - } - - // Don't allow to modify system template - if (id == Long.valueOf(1)) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); - ex.addProxyObject(template, id, "templateId"); - throw ex; - } - - // do a permission check - _accountMgr.checkAccess(account, AccessType.ModifyEntry, true, template); - - boolean updateNeeded = !(name == null && displayText == null && format == null && guestOSId == null && passwordEnabled == null - && bootable == null && sortKey == null); - if (!updateNeeded) { - return template; - } - - template = _templateDao.createForUpdate(id); - - if (name != null) { - template.setName(name); - } - - if (displayText != null) { - template.setDisplayText(displayText); - } - - if (sortKey != null) { - template.setSortKey(sortKey); - } - - ImageFormat imageFormat = null; - if (format != null) { - try { - imageFormat = ImageFormat.valueOf(format.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are " - + EnumUtils.listValues(ImageFormat.values())); - } - - template.setFormat(imageFormat); - } - - if (guestOSId != null) { - GuestOSVO guestOS = _guestOSDao.findById(guestOSId); - - if (guestOS == null) { - throw new InvalidParameterValueException("Please specify a valid guest OS ID."); - } else { - template.setGuestOSId(guestOSId); - } - } - - if (passwordEnabled != null) { - template.setEnablePassword(passwordEnabled); - } - - if (bootable != null) { - template.setBootable(bootable); - } - - _templateDao.update(id, template); - - return _templateDao.findById(id); - } @Override public Pair, Integer> searchForIPAddresses(ListPublicIpAddressesCmd cmd) { diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index 7c806447bc5..9ab51e5a667 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -18,6 +18,8 @@ package com.cloud.template; import java.util.List; +import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; +import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -125,4 +127,7 @@ public interface TemplateManager extends TemplateApiService{ List getImageStoreByTemplate(long templateId, Long zoneId); + + + } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 6640df208a5..9e524228fe1 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -40,11 +40,13 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.BaseListTemplateOrIsoPermissionsCmd; +import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoPermissionsCmd; import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd; import org.apache.cloudstack.api.command.user.iso.ListIsoPermissionsCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; +import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; import org.apache.cloudstack.api.command.user.iso.UpdateIsoPermissionsCmd; import org.apache.cloudstack.api.command.user.template.CopyTemplateCmd; import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd; @@ -52,6 +54,7 @@ import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd; import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; +import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -177,6 +180,7 @@ import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserAccountDao; import com.cloud.user.dao.UserDao; import com.cloud.uservm.UserVm; +import com.cloud.utils.EnumUtils; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; @@ -2225,5 +2229,97 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return stores; } + @Override + public VMTemplateVO updateTemplate(UpdateIsoCmd cmd) { + return updateTemplateOrIso(cmd); + } + @Override + public VMTemplateVO updateTemplate(UpdateTemplateCmd cmd) { + return updateTemplateOrIso(cmd); + } + + private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) { + Long id = cmd.getId(); + String name = cmd.getTemplateName(); + String displayText = cmd.getDisplayText(); + String format = cmd.getFormat(); + Long guestOSId = cmd.getOsTypeId(); + Boolean passwordEnabled = cmd.isPasswordEnabled(); + Boolean bootable = cmd.isBootable(); + Integer sortKey = cmd.getSortKey(); + Account account = UserContext.current().getCaller(); + + // verify that template exists + VMTemplateVO template = _tmpltDao.findById(id); + if (template == null || template.getRemoved() != null) { + InvalidParameterValueException ex = new InvalidParameterValueException("unable to find template/iso with specified id"); + ex.addProxyObject(template, id, "templateId"); + throw ex; + } + + // Don't allow to modify system template + if (id == Long.valueOf(1)) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to update template/iso of specified id"); + ex.addProxyObject(template, id, "templateId"); + throw ex; + } + + // do a permission check + _accountMgr.checkAccess(account, AccessType.ModifyEntry, true, template); + + boolean updateNeeded = !(name == null && displayText == null && format == null && guestOSId == null && passwordEnabled == null + && bootable == null && sortKey == null); + if (!updateNeeded) { + return template; + } + + template = _tmpltDao.createForUpdate(id); + + if (name != null) { + template.setName(name); + } + + if (displayText != null) { + template.setDisplayText(displayText); + } + + if (sortKey != null) { + template.setSortKey(sortKey); + } + + ImageFormat imageFormat = null; + if (format != null) { + try { + imageFormat = ImageFormat.valueOf(format.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new InvalidParameterValueException("Image format: " + format + " is incorrect. Supported formats are " + + EnumUtils.listValues(ImageFormat.values())); + } + + template.setFormat(imageFormat); + } + + if (guestOSId != null) { + GuestOSVO guestOS = _guestOSDao.findById(guestOSId); + + if (guestOS == null) { + throw new InvalidParameterValueException("Please specify a valid guest OS ID."); + } else { + template.setGuestOSId(guestOSId); + } + } + + if (passwordEnabled != null) { + template.setEnablePassword(passwordEnabled); + } + + if (bootable != null) { + template.setBootable(bootable); + } + + _tmpltDao.update(id, template); + + return _tmpltDao.findById(id); + } } From 1fe5d7c8867b25a6848f3cee434df3afb487dfa1 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 18 Apr 2013 01:56:34 -0700 Subject: [PATCH 033/303] need to download image to cache storage from s3/swift on mgt server for default system vm templates --- .../LocalNfsSecondaryStorageResource.java | 9 ++++ .../resource/NfsSecondaryStorageResource.java | 7 +++ .../command/AttachPrimaryDataStoreAnswer.java | 0 .../command/AttachPrimaryDataStoreCmd.java | 0 .../cloudstack/storage/command/CopyCmd.java | 0 .../storage/command/CopyCmdAnswer.java | 0 .../CopyTemplateToPrimaryStorageAnswer.java | 0 .../storage/command/CreateObjectAnswer.java | 0 .../storage/command/CreateObjectCommand.java | 0 .../command/CreatePrimaryDataStoreCmd.java | 0 .../storage/command/DeleteCommand.java | 0 .../command/StorageSubSystemCommand.java | 0 .../image/datastore/ImageStoreInfo.java | 0 .../cloudstack/storage/to/ImageStoreTO.java | 0 .../storage/to/NfsPrimaryDataStoreTO.java | 0 .../storage/to/PrimaryDataStoreTO.java | 0 .../storage/to/TemplateObjectTO.java | 0 .../cloudstack/storage/to/VolumeObjectTO.java | 0 .../manager/StorageCacheManagerImpl.java | 1 - .../storage/test/DirectAgentTest.java | 7 ++- .../cloudstack/storage/LocalHostEndpoint.java | 41 ++++++++++++++++ .../CreateVolumeFromBaseImageCommand.java | 49 ------------------- .../ObjectInDataStoreManagerImpl.java | 25 +++++++--- .../endpoint/DefaultEndPointSelector.java | 24 +++++++-- .../storage/to/ImageOnPrimayDataStoreTO.java | 44 ----------------- .../xen/resource/XcpOssResource.java | 3 +- .../resource/XenServerStorageResource.java | 9 +--- .../cloudstack/storage/test/VolumeTest.java | 12 ----- 28 files changed, 100 insertions(+), 131 deletions(-) create mode 100644 core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/CopyCmd.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/DeleteCommand.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/to/ImageStoreTO.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java (100%) rename engine/{storage => api}/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java (100%) create mode 100644 engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java new file mode 100644 index 00000000000..f0c43102d38 --- /dev/null +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -0,0 +1,9 @@ +package com.cloud.storage.resource; + +import org.springframework.stereotype.Component; + +@Component +public class LocalNfsSecondaryStorageResource extends + NfsSecondaryStorageResource { + +} diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 04b715d5268..d5dda68afb2 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -49,6 +49,7 @@ import java.util.concurrent.Callable; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.CopyCmd; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -219,10 +220,16 @@ SecondaryStorageResource { return execute((DeleteTemplateFromS3Command) cmd); } else if (cmd instanceof CleanupSnapshotBackupCommand){ return execute((CleanupSnapshotBackupCommand)cmd); + } else if (cmd instanceof CopyCmd) { + return execute((CopyCmd)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } + + protected Answer execute(CopyCmd cmd) { + return Answer.createUnsupportedCommandAnswer(cmd); + } @SuppressWarnings("unchecked") private String determineS3TemplateDirectory(final Long accountId, diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/CopyCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java rename to engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/DeleteCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/StorageSubSystemCommand.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java rename to engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/to/ImageStoreTO.java rename to engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java rename to engine/api/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java rename to engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java rename to engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java rename to engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.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 index c51ce6e6b5e..150c28930f5 100644 --- 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 @@ -135,7 +135,6 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - CommandResult result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index a5a4cb75877..c79326c3748 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -23,7 +23,6 @@ import java.util.UUID; import javax.inject.Inject; import org.apache.cloudstack.storage.to.ImageStoreTO; -import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.mockito.Mockito; @@ -126,10 +125,10 @@ public class DirectAgentTest extends CloudStackTestNGBase { @Test public void testDownloadTemplate() { - ImageOnPrimayDataStoreTO image = Mockito.mock(ImageOnPrimayDataStoreTO.class); + ImageStoreTO image = Mockito.mock(ImageStoreTO.class); PrimaryDataStoreTO primaryStore = Mockito.mock(PrimaryDataStoreTO.class); Mockito.when(primaryStore.getUuid()).thenReturn(this.getLocalStorageUuid()); - Mockito.when(image.getPrimaryDataStore()).thenReturn(primaryStore); + //Mockito.when(image.get).thenReturn(primaryStore); ImageStoreTO imageStore = Mockito.mock(ImageStoreTO.class); Mockito.when(imageStore.getType()).thenReturn("http"); @@ -138,7 +137,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { Mockito.when(template.getPath()).thenReturn(this.getTemplateUrl()); Mockito.when(template.getImageDataStore()).thenReturn(imageStore); - Mockito.when(image.getTemplate()).thenReturn(template); + //Mockito.when(image.getTemplate()).thenReturn(template); //CopyTemplateToPrimaryStorageCmd cmd = new CopyTemplateToPrimaryStorageCmd(image); Command cmd = null; try { diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java new file mode 100644 index 00000000000..665ed92ef54 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -0,0 +1,41 @@ +package org.apache.cloudstack.storage; + +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CopyCmd; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.resource.ServerResource; +import com.cloud.storage.resource.LocalNfsSecondaryStorageResource; +import com.cloud.utils.component.ComponentContext; + +public class LocalHostEndpoint implements EndPoint { + + ServerResource resource; + public LocalHostEndpoint() { + resource = ComponentContext.inject(LocalNfsSecondaryStorageResource.class); + } + @Override + public long getId() { + // TODO Auto-generated method stub + return 0; + } + + @Override + public Answer sendMessage(Command cmd) { + if (cmd instanceof CopyCmd) { + return resource.executeRequest(cmd); + } + // TODO Auto-generated method stub + return new Answer(cmd, false, "unsupported command:" + cmd.toString()); + } + + @Override + public void sendMessageAsync(Command cmd, + AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java b/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java deleted file mode 100644 index db96571c552..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/command/CreateVolumeFromBaseImageCommand.java +++ /dev/null @@ -1,49 +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.command; - -import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; -import org.apache.cloudstack.storage.to.VolumeObjectTO; - -import com.cloud.agent.api.Command; - -public class CreateVolumeFromBaseImageCommand extends Command implements StorageSubSystemCommand { - private final VolumeObjectTO volume; - private final ImageOnPrimayDataStoreTO image; - - public CreateVolumeFromBaseImageCommand(VolumeObjectTO volume, String image) { - this.volume = volume; - this.image = null; - } - - public VolumeObjectTO getVolume() { - return this.volume; - } - - public ImageOnPrimayDataStoreTO getImage() { - return this.image; - } - - @Override - public boolean executeInSequence() { - // TODO Auto-generated method stub - return false; - } - -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 89d61605de0..3c30de06440 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -44,7 +44,10 @@ import com.cloud.agent.api.Answer; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; +import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria2; @@ -75,6 +78,12 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { SnapshotDataFactory snapshotFactory; @Inject ObjectInDataStoreDao objInStoreDao; + @Inject + VMTemplateDao templateDao; + @Inject + SnapshotDao snapshotDao; + @Inject + VolumeDao volumeDao; protected StateMachine2 stateMachines; public ObjectInDataStoreManagerImpl() { @@ -116,13 +125,6 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); vo = templatePoolDao.persist(vo); } - } else if (dataStore.getRole() == DataStoreRole.ImageCache) { - ObjectInDataStoreVO vo = new ObjectInDataStoreVO(); - vo.setDataStoreRole(dataStore.getRole()); - vo.setDataStoreId(dataStore.getId()); - vo.setObjectType(obj.getType()); - vo.setObjectId(obj.getId()); - vo = objInStoreDao.persist(vo); } else { // Image store switch ( obj.getType()){ @@ -130,18 +132,27 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { TemplateDataStoreVO ts = new TemplateDataStoreVO(); ts.setTemplateId(obj.getId()); ts.setDataStoreId(dataStore.getId()); + if (dataStore.getRole() == DataStoreRole.ImageCache) { + ts.setInstallPath("/templates/" + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + } ts = templateDataStoreDao.persist(ts); break; case SNAPSHOT: SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); ss.setSnapshotId(obj.getId()); ss.setDataStoreId(dataStore.getId()); + if (dataStore.getRole() == DataStoreRole.ImageCache) { + ss.setInstallPath("/snapshots/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + } ss = snapshotDataStoreDao.persist(ss); break; case VOLUME: VolumeDataStoreVO vs = new VolumeDataStoreVO(); vs.setVolumeId(obj.getId()); vs.setDataStoreId(dataStore.getId()); + if (dataStore.getRole() == DataStoreRole.ImageCache) { + vs.setInstallPath("/volumes/" + volumeDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + } vs = volumeDataStoreDao.persist(vs); break; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 2d03c44b972..d641f21020a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -33,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.HypervisorHostEndPoint; +import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -70,6 +71,16 @@ public class DefaultEndPointSelector implements EndPointSelector { return false; } } + + protected boolean moveBetweenCacheAndImage(DataStore srcStore, DataStore destStore) { + DataStoreRole srcRole = srcStore.getRole(); + DataStoreRole destRole = destStore.getRole(); + if (srcRole == DataStoreRole.Image && destRole == DataStoreRole.ImageCache) { + return true; + } else { + return false; + } + } @DB protected EndPoint findEndPointInScope(Scope scope, String sqlBase) { @@ -146,12 +157,15 @@ public class DefaultEndPointSelector implements EndPointSelector { public EndPoint select(DataObject srcData, DataObject destData) { DataStore srcStore = srcData.getDataStore(); DataStore destStore = destData.getDataStore(); - if (srcData.getFormat() == DiskFormat.VMDK - || destData.getFormat() == DiskFormat.VMDK) { - // If any of data is for vmware, data moving should go to ssvm - - } else if (moveBetweenPrimaryImage(srcStore, destStore)) { + if (moveBetweenPrimaryImage(srcStore, destStore)) { return findEndPointForImageMove(srcStore, destStore); + } else if (moveBetweenCacheAndImage(srcStore, destStore)) { + EndPoint ep = findEndPointForImageMove(srcStore, destStore); + if (ep == null) { + //if there is no ssvm agent running, use mgt server + ep = new LocalHostEndpoint(); + } + return ep; } // TODO Auto-generated method stub return null; diff --git a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java b/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java deleted file mode 100644 index e3909187467..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/to/ImageOnPrimayDataStoreTO.java +++ /dev/null @@ -1,44 +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.to; - -import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; - -public class ImageOnPrimayDataStoreTO { - private final String pathOnPrimaryDataStore; - private PrimaryDataStoreTO dataStore; - private final TemplateObjectTO template; - public ImageOnPrimayDataStoreTO(TemplateOnPrimaryDataStoreInfo template) { - this.pathOnPrimaryDataStore = template.getPath(); - //this.dataStore = template.getPrimaryDataStore().getDataStoreTO(); - this.template = new TemplateObjectTO(template.getTemplate()); - } - - public String getPathOnPrimaryDataStore() { - return this.pathOnPrimaryDataStore; - } - - public PrimaryDataStoreTO getPrimaryDataStore() { - return this.dataStore; - } - - public TemplateObjectTO getTemplate() { - return this.template; - } -} diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java index 357b4333678..e5a95594720 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java @@ -20,7 +20,6 @@ package com.cloud.hypervisor.xen.resource; import java.io.File; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Set; import javax.ejb.Local; @@ -46,10 +45,10 @@ import com.cloud.utils.script.Script; import com.cloud.vm.VirtualMachine; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Types; +import com.xensource.xenapi.Types.XenAPIException; import com.xensource.xenapi.VBD; import com.xensource.xenapi.VDI; import com.xensource.xenapi.VM; -import com.xensource.xenapi.Types.XenAPIException; @Local(value=ServerResource.class) public class XcpOssResource extends CitrixResourceBase { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 1cd53351185..e7c009b00b1 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -39,10 +39,8 @@ import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; -import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; -import org.apache.cloudstack.storage.to.ImageOnPrimayDataStoreTO; import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; @@ -59,7 +57,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.DataStoreRole; @@ -93,8 +90,6 @@ public class XenServerStorageResource { return this.execute((AttachPrimaryDataStoreCmd)command); } else if (command instanceof CreatePrimaryDataStoreCmd) { return execute((CreatePrimaryDataStoreCmd) command); - } else if (command instanceof CreateVolumeFromBaseImageCommand) { - return execute((CreateVolumeFromBaseImageCommand)command); } else if (command instanceof CreateObjectCommand) { return execute((CreateObjectCommand) command); } else if (command instanceof DeleteVolumeCommand) { @@ -215,7 +210,7 @@ public class XenServerStorageResource { return new Answer(cmd, false, errorMsg); } - protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { + /* protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { VolumeObjectTO volume = cmd.getVolume(); ImageOnPrimayDataStoreTO baseImage = cmd.getImage(); Connection conn = hypervisorResource.getConnection(); @@ -232,7 +227,7 @@ public class XenServerStorageResource { } catch (XmlRpcException e) { return new Answer(cmd, false, e.toString()); } - } + }*/ protected SR getNfsSR(Connection conn, DecodedDataStore store) { diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java index dc29fb835d2..91bc7ea0117 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -23,12 +23,9 @@ import java.util.Map; import java.util.UUID; import javax.inject.Inject; -import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.apache.cloudstack.storage.command.CreateObjectAnswer; -import org.apache.cloudstack.storage.command.CreateVolumeFromBaseImageCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.junit.Before; import org.junit.Test; @@ -114,15 +111,6 @@ public class VolumeTest { Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); CreateObjectAnswer createVolumeFromImageAnswer = new CreateObjectAnswer(null,UUID.randomUUID().toString(), null); - try { - Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer); - } catch (AgentUnavailableException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (OperationTimedoutException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } //Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); From ef30ee52ee8ee57632f139fac1b49afde3c11040 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 18 Apr 2013 13:44:49 -0700 Subject: [PATCH 034/303] add copy stuff from s3 into nfs cache storage --- .../resource/NfsSecondaryStorageResource.java | 145 ++++++++++-------- .../cloudstack/storage/to/ImageStoreTO.java | 2 +- .../storage/test/DirectAgentTest.java | 2 +- .../ObjectInDataStoreManagerImpl.java | 2 +- .../vmware/VmwareServerDiscoverer.java | 8 +- .../vmware/manager/VmwareManagerImpl.java | 8 +- .../vmware/resource/VmwareResource.java | 4 +- ...VmwareSecondaryStorageResourceHandler.java | 4 +- 8 files changed, 97 insertions(+), 78 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index d5dda68afb2..3ad07589973 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -18,7 +18,6 @@ package com.cloud.storage.resource; import static com.cloud.utils.S3Utils.deleteDirectory; import static com.cloud.utils.S3Utils.getDirectory; -import static com.cloud.utils.S3Utils.putDirectory; import static com.cloud.utils.StringUtils.join; import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; import static java.lang.String.format; @@ -29,7 +28,6 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; @@ -49,6 +47,7 @@ import java.util.concurrent.Callable; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.CopyCmd; import org.apache.log4j.Logger; @@ -63,7 +62,6 @@ import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DeleteTemplateFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromS3Command; -import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; import com.cloud.agent.api.PingCommand; @@ -102,20 +100,19 @@ import com.cloud.exception.InternalErrorException; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.resource.ServerResourceBase; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.StorageLayer; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; -import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.TemplateLocation; +import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.UploadManager; import com.cloud.storage.template.UploadManagerImpl; import com.cloud.utils.NumbersUtil; import com.cloud.utils.S3Utils; -import com.cloud.utils.UriUtils; import com.cloud.utils.S3Utils.FileNamingStrategy; -import com.cloud.utils.S3Utils.ObjectNamingStrategy; -import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; @@ -208,8 +205,6 @@ SecondaryStorageResource { return execute((DeleteSnapshotsDirCommand)cmd); } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) { return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd); - } else if (cmd instanceof DownloadTemplateFromS3ToSecondaryStorageCommand) { - return execute((DownloadTemplateFromS3ToSecondaryStorageCommand) cmd); } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) { return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd); } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) { @@ -227,7 +222,80 @@ SecondaryStorageResource { } } + protected Answer downloadFromS3ToNfs(CopyCmd cmd, DataTO srcData, S3TO s3, + DataTO destData, NfsTO destImageStore) { + final String storagePath = destImageStore.getUrl(); + final String destPath = destData.getPath(); + + try { + + final File downloadDirectory = _storage + .getFile(determineStorageTemplatePath(storagePath, + destPath)); + downloadDirectory.mkdirs(); + + if (!downloadDirectory.exists()) { + final String errMsg = format( + "Unable to create directory " + + "download directory %1$s for download from S3.", downloadDirectory.getName() + ); + s_logger.error(errMsg); + return new Answer(cmd, false, errMsg); + } + + getDirectory(s3, s3.getBucketName(), + destPath, + downloadDirectory, new FileNamingStrategy() { + @Override + public String determineFileName(final String key) { + return substringAfterLast(key, S3Utils.SEPARATOR); + } + }); + + return new Answer(cmd, true, format("Successfully downloaded " + + "from S3 to directory %2$s", + downloadDirectory.getName())); + + } catch (Exception e) { + + final String errMsg = format("Failed to download" + + "due to $2%s", e.getMessage()); + s_logger.error(errMsg, e); + return new Answer(cmd, false, errMsg); + } + } + + protected Answer downloadFromSwiftToNfs(CopyCmd cmd, DataTO srcData, SwiftTO srcImageStore, + DataTO destData, NfsTO destImageStore) { + return Answer.createUnsupportedCommandAnswer(cmd); + } + protected Answer execute(CopyCmd cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + DataStoreTO srcDataStore = srcData.getDataStore(); + DataStoreTO destDataStore = destData.getDataStore(); + + if (srcDataStore.getRole() == DataStoreRole.Image + && destDataStore.getRole() == DataStoreRole.ImageCache + ) { + + if (!(destDataStore instanceof NfsTO)) { + s_logger.debug("only support nfs as cache storage"); + return Answer.createUnsupportedCommandAnswer(cmd); + } + + if (srcDataStore instanceof S3TO) { + return downloadFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, + destData, (NfsTO)destDataStore); + } else if (srcDataStore instanceof SwiftTO) { + return downloadFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, + destData, (NfsTO)destDataStore); + } else { + return Answer.createUnsupportedCommandAnswer(cmd); + } + + } return Answer.createUnsupportedCommandAnswer(cmd); } @@ -240,59 +308,9 @@ SecondaryStorageResource { @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, - final Long accountId, final Long templateId) { + String dataPath) { return join( - asList(getRootDir(storagePath), TEMPLATE_ROOT_DIR, accountId, - templateId), File.separator); - } - - private Answer execute( - final DownloadTemplateFromS3ToSecondaryStorageCommand cmd) { - - final S3TO s3 = cmd.getS3(); - final String storagePath = cmd.getStoragePath(); - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); - - try { - - final File downloadDirectory = _storage - .getFile(determineStorageTemplatePath(storagePath, - accountId, templateId)); - downloadDirectory.mkdirs(); - - if (!downloadDirectory.exists()) { - final String errMsg = format( - "Unable to create directory " - + "download directory %1$s for download of template id " - + "%2$s from S3.", downloadDirectory.getName(), - templateId); - s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); - } - - getDirectory(s3, s3.getBucketName(), - determineS3TemplateDirectory(accountId, templateId), - downloadDirectory, new FileNamingStrategy() { - @Override - public String determineFileName(final String key) { - return substringAfterLast(key, S3Utils.SEPARATOR); - } - }); - - return new Answer(cmd, true, format("Successfully downloaded " - + "template id %1$s from S3 to directory %2$s", templateId, - downloadDirectory.getName())); - - } catch (Exception e) { - - final String errMsg = format("Failed to upload template id %1$s " - + "due to $2%s", templateId, e.getMessage()); - s_logger.error(errMsg, e); - return new Answer(cmd, false, errMsg); - - } - + asList(getRootDir(storagePath), dataPath), File.separator); } private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) { @@ -411,7 +429,7 @@ SecondaryStorageResource { } private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) { - +/* final S3TO s3 = cmd.getS3(); final Long accountId = cmd.getAccountId(); final Long templateId = cmd.getTemplateId(); @@ -485,7 +503,8 @@ SecondaryStorageResource { return new Answer(cmd, false, errMsg); } - +*/ + return new Answer(cmd, false, "not supported "); } private Answer execute(DeleteObjectFromSwiftCommand cmd) { diff --git a/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java index a9d95e812e1..28d5ef3d6aa 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -38,7 +38,7 @@ public class ImageStoreTO implements DataStoreTO { this.role = dataStore.getRole(); } - public String getType() { + public String getProtocol() { return this.type; } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index c79326c3748..bf3acb4759a 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -131,7 +131,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { //Mockito.when(image.get).thenReturn(primaryStore); ImageStoreTO imageStore = Mockito.mock(ImageStoreTO.class); - Mockito.when(imageStore.getType()).thenReturn("http"); + Mockito.when(imageStore.getProtocol()).thenReturn("http"); TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class); Mockito.when(template.getPath()).thenReturn(this.getTemplateUrl()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 3c30de06440..52ed312c0d9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -133,7 +133,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { ts.setTemplateId(obj.getId()); ts.setDataStoreId(dataStore.getId()); if (dataStore.getRole() == DataStoreRole.ImageCache) { - ts.setInstallPath("/templates/" + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + ts.setInstallPath("template/tmpl/" + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); } ts = templateDataStoreDao.persist(ts); break; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 2f82b534af2..c4b53c258d6 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -312,7 +312,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements .decode(uriFromCluster.getPath())); if (morCluster == null - || !morCluster.getType().equalsIgnoreCase( + || !morCluster.getProtocol().equalsIgnoreCase( "ClusterComputeResource")) { s_logger.warn("Cluster url does not point to a valid vSphere cluster, url: " + clusterDetails.get("url")); @@ -345,7 +345,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements details.put("url", hostMo.getHostName()); details.put("username", username); details.put("password", password); - String guid = morHost.getType() + ":" + morHost.getValue() + String guid = morHost.getProtocol() + ":" + morHost.getValue() + "@" + url.getHost(); details.put("guid", guid); @@ -402,7 +402,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements for (ManagedObjectReference morHost : morHosts) { ManagedObjectReference morParent = (ManagedObjectReference) context .getVimClient().getDynamicProperty(morHost, "parent"); - if (morParent.getType().equalsIgnoreCase( + if (morParent.getProtocol().equalsIgnoreCase( "ClusterComputeResource")) return false; } @@ -410,7 +410,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements for (ManagedObjectReference morHost : morHosts) { ManagedObjectReference morParent = (ManagedObjectReference) context .getVimClient().getDynamicProperty(morHost, "parent"); - if (!morParent.getType().equalsIgnoreCase( + if (!morParent.getProtocol().equalsIgnoreCase( "ClusterComputeResource")) return false; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index b2e37685d17..adcf23b6837 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -336,7 +336,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw if(mor != null) { List returnedHostList = new ArrayList(); - if(mor.getType().equals("ComputeResource")) { + if(mor.getProtocol().equals("ComputeResource")) { List hosts = (List)serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert(hosts != null && hosts.size() > 0); @@ -346,7 +346,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(hosts.get(0)); return returnedHostList; - } else if(mor.getType().equals("ClusterComputeResource")) { + } else if(mor.getProtocol().equals("ClusterComputeResource")) { List hosts = (List)serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert(hosts != null); @@ -368,14 +368,14 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw returnedHostList.add(morHost); } return returnedHostList; - } else if(mor.getType().equals("HostSystem")) { + } else if(mor.getProtocol().equals("HostSystem")) { // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, mor); prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(mor); return returnedHostList; } else { - s_logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); + s_logger.error("Unsupport host type " + mor.getProtocol() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); return null; } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 4079d0d65b5..b7218ef9f57 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -4470,7 +4470,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa ManagedObjectReference morParent = vmOwnerHost.getParentMor(); HashMap portInfo; - if(morParent.getType().equalsIgnoreCase("ClusterComputeResource")) { + if(morParent.getProtocol().equalsIgnoreCase("ClusterComputeResource")) { ClusterMO clusterMo = new ClusterMO(vmOwnerHost.getContext(), morParent); portInfo = clusterMo.getVmVncPortsOnCluster(); } else { @@ -5067,7 +5067,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa @Override public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { - if (_morHyperHost.getType().equalsIgnoreCase("HostSystem")) { + if (_morHyperHost.getProtocol().equalsIgnoreCase("HostSystem")) { return new HostMO(context, _morHyperHost); } return new ClusterMO(context, _morHyperHost); diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java index 566e750c3fe..bb5abb94840 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java @@ -221,7 +221,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe morHyperHost.setType(hostTokens[0]); morHyperHost.setValue(hostTokens[1]); - if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { + if(morHyperHost.getProtocol().equalsIgnoreCase("HostSystem")) { HostMO hostMo = new HostMO(context, morHyperHost); try { @@ -278,7 +278,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe morHyperHost.setType(hostTokens[0]); morHyperHost.setValue(hostTokens[1]); - if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { + if(morHyperHost.getProtocol().equalsIgnoreCase("HostSystem")) { HostMO hostMo = new HostMO(context, morHyperHost); try { VmwareHypervisorHostNetworkSummary netSummary = hostMo.getHyperHostNetworkSummary( From 7ba1a8fa2154ab0db543f4df42310208d1aae881 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 18 Apr 2013 13:52:15 -0700 Subject: [PATCH 035/303] Populate hypervisor_type column in registering ISO by referring it from guest os id to make listIsos and listTemplates implementation more consistent. --- .../com/cloud/storage/GuestOSHypervisor.java | 28 +++++++ client/tomcatconf/applicationContext.xml.in | 2 + .../cloud/storage/GuestOSHypervisorVO.java | 73 +++++++++++++++++++ .../storage/dao/GuestOSHypervisorDao.java | 27 +++++++ .../storage/dao/GuestOSHypervisorDaoImpl.java | 49 +++++++++++++ .../cloud/template/TemplateAdapterBase.java | 9 ++- 6 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 api/src/com/cloud/storage/GuestOSHypervisor.java create mode 100644 core/src/com/cloud/storage/GuestOSHypervisorVO.java create mode 100644 server/src/com/cloud/storage/dao/GuestOSHypervisorDao.java create mode 100644 server/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java diff --git a/api/src/com/cloud/storage/GuestOSHypervisor.java b/api/src/com/cloud/storage/GuestOSHypervisor.java new file mode 100644 index 00000000000..f022722af04 --- /dev/null +++ b/api/src/com/cloud/storage/GuestOSHypervisor.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 com.cloud.storage; + +import org.apache.cloudstack.api.InternalIdentity; + +public interface GuestOSHypervisor extends InternalIdentity { + + String getHypervisorType(); + + String getGuestOsName(); + + long getGuestOsId(); +} diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 7ad3bb50f9c..7bbcf0959a8 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -212,6 +212,8 @@ + + diff --git a/core/src/com/cloud/storage/GuestOSHypervisorVO.java b/core/src/com/cloud/storage/GuestOSHypervisorVO.java new file mode 100644 index 00000000000..5ab34809280 --- /dev/null +++ b/core/src/com/cloud/storage/GuestOSHypervisorVO.java @@ -0,0 +1,73 @@ +// 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.storage; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +@Entity +@Table(name="guest_os_hypervisor") +public class GuestOSHypervisorVO implements GuestOSHypervisor { + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="guest_os_id") + private long guestOsId; + + @Column(name="guest_os_name") + String guestOsName; + + @Column(name="hypervisor_type") + String hypervisorType; + + + @Override + public long getId() { + return id; + } + + + @Override + public String getHypervisorType() { + return hypervisorType; + } + + + @Override + public String getGuestOsName() { + return guestOsName; + } + + + @Override + public long getGuestOsId() { + return guestOsId; + } + + +} diff --git a/server/src/com/cloud/storage/dao/GuestOSHypervisorDao.java b/server/src/com/cloud/storage/dao/GuestOSHypervisorDao.java new file mode 100644 index 00000000000..945a542d9e0 --- /dev/null +++ b/server/src/com/cloud/storage/dao/GuestOSHypervisorDao.java @@ -0,0 +1,27 @@ +// 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.storage.dao; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; +import com.cloud.utils.db.GenericDao; + +public interface GuestOSHypervisorDao extends GenericDao { + + HypervisorType findHypervisorTypeByGuestOsId(long guestOsId); + +} diff --git a/server/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java b/server/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java new file mode 100644 index 00000000000..48de6e9ae80 --- /dev/null +++ b/server/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java @@ -0,0 +1,49 @@ +// 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.storage.dao; + +import javax.ejb.Local; + +import org.springframework.stereotype.Component; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.GuestOSHypervisorVO; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + +@Component +@Local(value = { GuestOSHypervisorDao.class }) +public class GuestOSHypervisorDaoImpl extends GenericDaoBase implements GuestOSHypervisorDao { + + protected final SearchBuilder guestOsSearch; + + protected GuestOSHypervisorDaoImpl() { + guestOsSearch = createSearchBuilder(); + guestOsSearch.and("guest_os_id", guestOsSearch.entity().getGuestOsId(), SearchCriteria.Op.EQ); + guestOsSearch.done(); + } + + @Override + public HypervisorType findHypervisorTypeByGuestOsId(long guestOsId) { + SearchCriteria sc = guestOsSearch.create(); + sc.setParameters("guest_os_id", guestOsId); + GuestOSHypervisorVO goh = findOneBy(sc); + return HypervisorType.getType(goh.getHypervisorType()); + } + +} diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 987e6ed6ab5..9826298d50b 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -50,6 +50,7 @@ import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.TemplateProfile; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; @@ -81,6 +82,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat protected @Inject UsageEventDao _usageEventDao; protected @Inject HostDao _hostDao; protected @Inject UserVmDao _userVmDao; + protected @Inject GuestOSHypervisorDao _osHyperDao; protected @Inject ResourceLimitService _resourceLimitMgr; protected @Inject DataStoreManager storeMgr; @Inject TemplateManager templateMgr; @@ -232,9 +234,14 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); _accountMgr.checkAccess(caller, null, true, owner); + HypervisorType hyperType = HypervisorType.None; + if ( cmd.getOsTypeId() != null ){ + hyperType = _osHyperDao.findHypervisorTypeByGuestOsId(cmd.getOsTypeId()); + } + return prepare(true, UserContext.current().getCallerUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false, true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), - cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false); + cmd.getZoneId(), hyperType, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false); } protected VMTemplateVO persistTemplate(TemplateProfile profile) { From 539824797c01a992d3f7868f5ad18848e066dbca Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 19 Apr 2013 16:10:09 -0700 Subject: [PATCH 036/303] Refactor listTemplatesCmd and listIsoCmd to use db view. --- .../com/cloud/server/ManagementService.java | 22 - .../cloudstack/api/ResponseGenerator.java | 14 +- .../admin/template/PrepareTemplateCmd.java | 2 +- .../api/command/user/iso/ListIsosCmd.java | 11 +- .../api/command/user/iso/RegisterIsoCmd.java | 6 +- .../api/command/user/iso/UpdateIsoCmd.java | 2 +- .../user/template/CopyTemplateCmd.java | 2 +- .../user/template/ListTemplatesCmd.java | 16 +- .../user/template/RegisterTemplateCmd.java | 2 +- .../user/template/UpdateTemplateCmd.java | 2 +- .../api/response/TemplateResponse.java | 35 +- .../api/response/TemplateZoneResponse.java | 90 ++ .../apache/cloudstack/query/QueryService.java | 7 + server/src/com/cloud/api/ApiDBUtils.java | 36 + .../src/com/cloud/api/ApiResponseHelper.java | 814 +++++-------- .../com/cloud/api/query/QueryManagerImpl.java | 321 ++++++ .../cloud/api/query/ViewResponseHelper.java | 53 + .../cloud/api/query/dao/TemplateJoinDao.java | 42 + .../api/query/dao/TemplateJoinDaoImpl.java | 441 ++++++++ .../cloud/api/query/vo/TemplateJoinVO.java | 1006 +++++++++++++++++ .../cloud/server/ManagementServerImpl.java | 66 +- .../com/cloud/storage/dao/VMTemplateDao.java | 17 +- .../cloud/storage/dao/VMTemplateDaoImpl.java | 36 +- .../cloud/template/TemplateManagerImpl.java | 1 + setup/db/db/schema-410to420.sql | 95 ++ 25 files changed, 2460 insertions(+), 679 deletions(-) create mode 100644 api/src/org/apache/cloudstack/api/response/TemplateZoneResponse.java create mode 100644 server/src/com/cloud/api/query/dao/TemplateJoinDao.java create mode 100644 server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java create mode 100644 server/src/com/cloud/api/query/vo/TemplateJoinVO.java diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index d58ea3ec384..674f67c2c51 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -219,28 +219,6 @@ public interface ManagementService { */ List listCapacities(ListCapacityCmd cmd); - /** - * List ISOs that match the specified criteria. - * - * @param cmd - * The command that wraps the (optional) templateId, name, keyword, templateFilter, bootable, account, - * and zoneId - * parameters. - * @return list of ISOs - */ - Set> listIsos(ListIsosCmd cmd); - - /** - * List templates that match the specified criteria. - * - * @param cmd - * The command that wraps the (optional) templateId, name, keyword, templateFilter, bootable, account, - * and zoneId - * parameters. - * @return list of ISOs - */ - Set> listTemplates(ListTemplatesCmd cmd); - /** * List system VMs by the given search criteria diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 3d381b0300a..77d3bea59cd 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -241,7 +241,7 @@ public interface ResponseGenerator { Host findHostById(Long hostId); - List createTemplateResponses(long templateId, long zoneId, boolean readyOnly); + //List createTemplateResponses(long templateId, long zoneId, boolean readyOnly); VpnUsersResponse createVpnUserResponse(VpnUser user); @@ -267,7 +267,9 @@ public interface ResponseGenerator { //List createEventResponse(EventJoinVO... events); - TemplateResponse createIsoResponse(VirtualMachineTemplate result); + TemplateResponse createTemplateUpdateResponse(VirtualMachineTemplate result); + + List createTemplateResponses(VirtualMachineTemplate result, Long zoneId, boolean readyOnly); List createCapacityResponse(List result, DecimalFormat format); @@ -287,13 +289,13 @@ public interface ResponseGenerator { Long getSecurityGroupId(String groupName, long accountId); - List createIsoResponses(long isoId, Long zoneId, boolean readyOnly); + List createIsoResponses(VirtualMachineTemplate iso, Long zoneId, boolean readyOnly); + + // List createIsoResponses(long isoId, Long zoneId, boolean readyOnly); + //List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly); ProjectResponse createProjectResponse(Project project); - - List createIsoResponses(VirtualMachineTemplate iso, long zoneId, boolean readyOnly); - List createTemplateResponses(long templateId, Long vmId); FirewallResponse createFirewallResponse(FirewallRule fwRule); diff --git a/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java index 7d41d10ae08..aee35ade978 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/template/PrepareTemplateCmd.java @@ -80,7 +80,7 @@ public class PrepareTemplateCmd extends BaseCmd { ListResponse response = new ListResponse(); VirtualMachineTemplate vmTemplate = _templateService.prepareTemplate(templateId, zoneId); - List templateResponses = _responseGenerator.createTemplateResponses(vmTemplate.getId(), zoneId, true); + List templateResponses = _responseGenerator.createTemplateResponses(vmTemplate, zoneId, true); response.setResponses(templateResponses); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java index 3219601156e..b490ca9966a 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ListIsosCmd.java @@ -148,16 +148,7 @@ public class ListIsosCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - Set> isoZonePairSet = _mgr.listIsos(this); - ListResponse response = new ListResponse(); - List templateResponses = new ArrayList(); - - for (Pair iso : isoZonePairSet) { - List responses = new ArrayList(); - responses = _responseGenerator.createIsoResponses(iso.first(), iso.second(), listInReadyState()); - templateResponses.addAll(responses); - } - response.setResponses(templateResponses); + ListResponse response = _queryService.listIsos(this); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java index 284d5530846..0fa47eb1d17 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/RegisterIsoCmd.java @@ -88,7 +88,7 @@ public class RegisterIsoCmd extends BaseCmd { @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, entityType = ProjectResponse.class, description="Register iso for the project") private Long projectId; - + @Parameter(name=ApiConstants.IMAGE_STORE_UUID, type=CommandType.STRING, description="Image store uuid") private String imageStoreUuid; @@ -144,7 +144,7 @@ public class RegisterIsoCmd extends BaseCmd { public String getChecksum() { return checksum; } - + public String getImageStoreUuid() { return this.imageStoreUuid; } @@ -173,7 +173,7 @@ public class RegisterIsoCmd extends BaseCmd { VirtualMachineTemplate template = _templateService.registerIso(this); if (template != null) { ListResponse response = new ListResponse(); - List templateResponses = _responseGenerator.createIsoResponses(template.getId(), zoneId, false); + List templateResponses = _responseGenerator.createIsoResponses(template, zoneId, false); response.setResponses(templateResponses); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java index 1384fa8c573..1d848472fad 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/UpdateIsoCmd.java @@ -68,7 +68,7 @@ public class UpdateIsoCmd extends BaseUpdateTemplateOrIsoCmd { public void execute(){ VirtualMachineTemplate result = _templateService.updateTemplate(this); if (result != null) { - TemplateResponse response = _responseGenerator.createIsoResponse(result); + TemplateResponse response = _responseGenerator.createTemplateUpdateResponse(result); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java index a4f05821244..34ee4bdc786 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/CopyTemplateCmd.java @@ -124,7 +124,7 @@ public class CopyTemplateCmd extends BaseAsyncCmd { VirtualMachineTemplate template = _templateService.copyTemplate(this); if (template != null){ - List listResponse = _responseGenerator.createTemplateResponses(template.getId(), getDestinationZoneId(), false); + List listResponse = _responseGenerator.createTemplateResponses(template, getDestinationZoneId(), false); TemplateResponse response = new TemplateResponse(); if (listResponse != null && !listResponse.isEmpty()) { response = listResponse.get(0); diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java index aeb76f507f3..0b937be6d59 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ListTemplatesCmd.java @@ -26,6 +26,7 @@ import org.apache.cloudstack.api.BaseListTaggedResourcesCmd; import org.apache.cloudstack.api.Parameter; import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.VolumeResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.log4j.Logger; @@ -55,7 +56,7 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the template name") private String templateName; - @Parameter(name=ApiConstants.TEMPLATE_FILTER, type=CommandType.STRING, required=true, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " + + @Parameter(name=ApiConstants.TEMPLATE_FILTER, type=CommandType.STRING, required=true, description="possible values are \"featured\", \"self\", \"selfexecutable\",\"sharedexecutable\",\"executable\", and \"community\". " + "* featured : templates that have been marked as featured and public. " + "* self : templates that have been registered or created by the calling user. " + "* selfexecutable : same as self, but only returns templates that can be used to deploy a new VM. " + @@ -119,18 +120,7 @@ public class ListTemplatesCmd extends BaseListTaggedResourcesCmd { @Override public void execute(){ - Set> templateZonePairSet = _mgr.listTemplates(this); - - ListResponse response = new ListResponse(); - List templateResponses = new ArrayList(); - - for (Pair template : templateZonePairSet) { - List responses = new ArrayList(); - responses = _responseGenerator.createTemplateResponses(template.first().longValue(), template.second(), listInReadyState()); - templateResponses.addAll(responses); - } - - response.setResponses(templateResponses); + ListResponse response = _queryService.listTemplates(this); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java index f93c9f4254c..974edb37537 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/RegisterTemplateCmd.java @@ -230,7 +230,7 @@ public class RegisterTemplateCmd extends BaseCmd { VirtualMachineTemplate template = _templateService.registerTemplate(this); if (template != null){ ListResponse response = new ListResponse(); - List templateResponses = _responseGenerator.createTemplateResponses(template.getId(), zoneId, false); + List templateResponses = _responseGenerator.createTemplateResponses(template, zoneId, false); response.setResponses(templateResponses); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java index e342fb1c204..9f55f9df6c7 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/UpdateTemplateCmd.java @@ -68,7 +68,7 @@ public class UpdateTemplateCmd extends BaseUpdateTemplateOrIsoCmd { public void execute(){ VirtualMachineTemplate result = _templateService.updateTemplate(this); if (result != null) { - TemplateResponse response = _responseGenerator.createIsoResponse(result); + TemplateResponse response = _responseGenerator.createTemplateUpdateResponse(result); response.setObjectName("template"); response.setResponseName(getCommandName()); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java index ed933ff18c3..225edd553db 100644 --- a/api/src/org/apache/cloudstack/api/response/TemplateResponse.java +++ b/api/src/org/apache/cloudstack/api/response/TemplateResponse.java @@ -17,8 +17,10 @@ package org.apache.cloudstack.api.response; import java.util.Date; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponse; @@ -31,7 +33,7 @@ import com.google.gson.annotations.SerializedName; @EntityReference(value=VirtualMachineTemplate.class) @SuppressWarnings("unused") -public class TemplateResponse extends BaseResponse implements ControlledEntityResponse { +public class TemplateResponse extends BaseResponse implements ControlledViewEntityResponse { @SerializedName(ApiConstants.ID) @Param(description="the template ID") private String id; @@ -82,6 +84,8 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account name to which the template belongs") private String account; + //TODO: since a template can be associated to more than one zones, this model is not accurate. For backward-compatibility, keep these fields + // here, but add a zones field to capture multiple zones. @SerializedName(ApiConstants.ZONE_ID) @Param(description="the ID of the zone for this template") private String zoneId; @@ -133,12 +137,20 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe @SerializedName(ApiConstants.DETAILS) @Param(description="additional key/value details tied with template") private Map details; + @SerializedName("zones") @Param(description="list of zones associated with tempate", responseObject = TemplateZoneResponse.class) + private Set zones; + @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with tempate", responseObject = ResourceTagResponse.class) - private List tags; + private Set tags; @SerializedName(ApiConstants.SSHKEY_ENABLED) @Param(description="true if template is sshkey enabled, false otherwise") private Boolean sshKeyEnabled; + public TemplateResponse(){ + zones = new LinkedHashSet(); + tags = new LinkedHashSet(); + } + @Override public String getObjectId() { return this.getId(); @@ -288,12 +300,29 @@ public class TemplateResponse extends BaseResponse implements ControlledEntityRe this.details = details; } - public void setTags(List tags) { + public void setTags(Set tags) { this.tags = tags; } + public void addTag(ResourceTagResponse tag){ + this.tags.add(tag); + } + + public void setZones(Set zones){ + this.zones = zones; + } + + public void addZone(TemplateZoneResponse zone){ + this.zones.add(zone); + } + public void setSshKeyEnabled(boolean sshKeyEnabled) { this.sshKeyEnabled = sshKeyEnabled; } + public String getZoneId() { + return zoneId; + } + + } diff --git a/api/src/org/apache/cloudstack/api/response/TemplateZoneResponse.java b/api/src/org/apache/cloudstack/api/response/TemplateZoneResponse.java new file mode 100644 index 00000000000..9d26ad9fc10 --- /dev/null +++ b/api/src/org/apache/cloudstack/api/response/TemplateZoneResponse.java @@ -0,0 +1,90 @@ +// 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.response; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +public class TemplateZoneResponse extends BaseResponse { + @SerializedName(ApiConstants.ZONE_ID) @Param(description="the ID of the zone for the template") + private String zoneId; + + @SerializedName(ApiConstants.ZONE_NAME) @Param(description="the name of the zone for the template") + private String zoneName; + + + public TemplateZoneResponse(){ + super(); + } + + public TemplateZoneResponse(String zoneId, String zoneName){ + super(); + this.zoneId = zoneId; + this.zoneName = zoneName; + } + + + + public String getZoneId() { + return zoneId; + } + + public void setZoneId(String zoneId) { + this.zoneId = zoneId; + } + + public String getZoneName() { + return zoneName; + } + + public void setZoneName(String zoneName) { + this.zoneName = zoneName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + String oid = this.getZoneId(); + result = prime * result + ((oid== null) ? 0 : oid.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateZoneResponse other = (TemplateZoneResponse) obj; + String oid = this.getZoneId(); + if (oid == null) { + if (other.getZoneId() != null) + return false; + } else if (!oid.equals(other.getZoneId())) + return false; + else if ( this.getZoneName().equals(other.getZoneName())) + return false; + return true; + } + +} diff --git a/api/src/org/apache/cloudstack/query/QueryService.java b/api/src/org/apache/cloudstack/query/QueryService.java index 66f63993dfd..4efbd1c2232 100644 --- a/api/src/org/apache/cloudstack/query/QueryService.java +++ b/api/src/org/apache/cloudstack/query/QueryService.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; +import org.apache.cloudstack.api.command.user.iso.ListIsosCmd; import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; @@ -31,6 +32,7 @@ import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd; import org.apache.cloudstack.api.command.user.project.ListProjectsCmd; import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd; import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; +import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd; import org.apache.cloudstack.api.command.user.vm.ListVMsCmd; import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; @@ -51,6 +53,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.SecurityGroupResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; +import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; @@ -101,4 +104,8 @@ public interface QueryService { public ListResponse searchForServiceOfferings(ListServiceOfferingsCmd cmd); public ListResponse listDataCenters(ListZonesByCmd cmd); + + public ListResponse listTemplates(ListTemplatesCmd cmd); + + public ListResponse listIsos(ListIsosCmd cmd); } diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 6b8607f6a85..00358d7f0bd 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -42,6 +42,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.SecurityGroupResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; +import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; @@ -65,6 +66,7 @@ import com.cloud.api.query.dao.ResourceTagJoinDao; import com.cloud.api.query.dao.SecurityGroupJoinDao; import com.cloud.api.query.dao.ServiceOfferingJoinDao; import com.cloud.api.query.dao.StoragePoolJoinDao; +import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.api.query.dao.UserAccountJoinDao; import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.dao.VolumeJoinDao; @@ -84,6 +86,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.SecurityGroupJoinVO; import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.api.query.vo.StoragePoolJoinVO; +import com.cloud.api.query.vo.TemplateJoinVO; import com.cloud.api.query.vo.UserAccountJoinVO; import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.VolumeJoinVO; @@ -240,6 +243,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.template.TemplateManager; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.AccountDetailsDao; import com.cloud.user.AccountVO; @@ -369,6 +373,7 @@ public class ApiDBUtils { static ImageStoreJoinDao _imageStoreJoinDao; static AccountJoinDao _accountJoinDao; static AsyncJobJoinDao _jobJoinDao; + static TemplateJoinDao _templateJoinDao; static PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao; static PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao; @@ -474,6 +479,7 @@ public class ApiDBUtils { @Inject private ImageStoreJoinDao imageStoreJoinDao; @Inject private AccountJoinDao accountJoinDao; @Inject private AsyncJobJoinDao jobJoinDao; + @Inject private TemplateJoinDao templateJoinDao; @Inject private PhysicalNetworkTrafficTypeDao physicalNetworkTrafficTypeDao; @Inject private PhysicalNetworkServiceProviderDao physicalNetworkServiceProviderDao; @@ -575,6 +581,7 @@ public class ApiDBUtils { _imageStoreJoinDao = imageStoreJoinDao; _accountJoinDao = accountJoinDao; _jobJoinDao = jobJoinDao; + _templateJoinDao = templateJoinDao; _physicalNetworkTrafficTypeDao = physicalNetworkTrafficTypeDao; _physicalNetworkServiceProviderDao = physicalNetworkServiceProviderDao; @@ -1606,4 +1613,33 @@ public class ApiDBUtils { public static List findNicSecondaryIps(long nicId) { return _nicSecondaryIpDao.listByNicId(nicId); } + + + public static TemplateResponse newTemplateUpdateResponse(TemplateJoinVO vr) { + return _templateJoinDao.newUpdateResponse(vr); + } + + + public static TemplateResponse newTemplateResponse(TemplateJoinVO vr) { + return _templateJoinDao.newTemplateResponse(vr); + } + + + public static TemplateResponse newIsoResponse(TemplateJoinVO vr) { + return _templateJoinDao.newIsoResponse(vr); + } + + public static TemplateResponse fillTemplateDetails(TemplateResponse vrData, TemplateJoinVO vr){ + return _templateJoinDao.setTemplateResponse(vrData, vr); + } + + public static List newTemplateView(VirtualMachineTemplate vr){ + return _templateJoinDao.newTemplateView(vr); + } + + + public static List newTemplateView(VirtualMachineTemplate vr, long zoneId, boolean readyOnly){ + return _templateJoinDao.newTemplateView(vr, zoneId, readyOnly); + } + } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index e9255c452f4..a0c9d38cd24 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -151,6 +151,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.SecurityGroupJoinVO; import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.api.query.vo.StoragePoolJoinVO; +import com.cloud.api.query.vo.TemplateJoinVO; import com.cloud.api.query.vo.UserAccountJoinVO; import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.VolumeJoinVO; @@ -281,8 +282,10 @@ public class ApiResponseHelper implements ResponseGenerator { public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class); private static final DecimalFormat s_percentFormat = new DecimalFormat("##.##"); - @Inject private EntityManager _entityMgr = null; - @Inject private UsageService _usageSvc = null; + @Inject + private EntityManager _entityMgr = null; + @Inject + private UsageService _usageSvc = null; @Override public UserResponse createUserResponse(User user) { @@ -290,9 +293,8 @@ public class ApiResponseHelper implements ResponseGenerator { return ApiDBUtils.newUserResponse(vUser); } - - - // this method is used for response generation via createAccount (which creates an account + user) + // this method is used for response generation via createAccount (which + // creates an account + user) @Override public AccountResponse createUserAccountResponse(UserAccount user) { return ApiDBUtils.newAccountResponse(ApiDBUtils.findAccountViewById(user.getAccountId())); @@ -304,7 +306,6 @@ public class ApiResponseHelper implements ResponseGenerator { return ApiDBUtils.newAccountResponse(vUser); } - @Override public UserResponse createUserResponse(UserAccount user) { UserAccountJoinVO vUser = ApiDBUtils.newUserView(user); @@ -352,8 +353,8 @@ public class ApiResponseHelper implements ResponseGenerator { populateDomain(resourceLimitResponse, accountTemp.getDomainId()); } resourceLimitResponse.setResourceType(Integer.valueOf(limit.getType().getOrdinal()).toString()); - if(limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) { - resourceLimitResponse.setMax((long) Math.ceil(limit.getMax()/ResourceType.bytesToGiB)); + if (limit.getType() == ResourceType.primary_storage || limit.getType() == ResourceType.secondary_storage) { + resourceLimitResponse.setMax((long) Math.ceil(limit.getMax() / ResourceType.bytesToGiB)); } else { resourceLimitResponse.setMax(limit.getMax()); } @@ -420,7 +421,7 @@ public class ApiResponseHelper implements ResponseGenerator { snapshotResponse.setIntervalType(ApiDBUtils.getSnapshotIntervalTypes(snapshot.getId())); snapshotResponse.setState(snapshot.getState()); - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Snapshot, snapshot.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -443,9 +444,9 @@ public class ApiResponseHelper implements ResponseGenerator { vmSnapshotResponse.setDescription(vmSnapshot.getDescription()); vmSnapshotResponse.setDisplayName(vmSnapshot.getDisplayName()); UserVm vm = ApiDBUtils.findUserVmById(vmSnapshot.getVmId()); - if(vm!=null) + if (vm != null) vmSnapshotResponse.setVirtualMachineid(vm.getUuid()); - if(vmSnapshot.getParent() != null) + if (vmSnapshot.getParent() != null) vmSnapshotResponse.setParentName(ApiDBUtils.getVMSnapshotById(vmSnapshot.getParent()).getDisplayName()); vmSnapshotResponse.setCurrent(vmSnapshot.getCurrent()); vmSnapshotResponse.setType(vmSnapshot.getType().toString()); @@ -542,9 +543,9 @@ public class ApiResponseHelper implements ResponseGenerator { // get start ip and end ip of corresponding vlan String ipRange = vlan.getIpRange(); if (ipRange != null) { - String[] range = ipRange.split("-"); - vlanResponse.setStartIp(range[0]); - vlanResponse.setEndIp(range[1]); + String[] range = ipRange.split("-"); + vlanResponse.setStartIp(range[0]); + vlanResponse.setEndIp(range[1]); } vlanResponse.setIp6Gateway(vlan.getIp6Gateway()); @@ -552,9 +553,9 @@ public class ApiResponseHelper implements ResponseGenerator { String ip6Range = vlan.getIp6Range(); if (ip6Range != null) { - String[] range = ip6Range.split("-"); - vlanResponse.setStartIpv6(range[0]); - vlanResponse.setEndIpv6(range[1]); + String[] range = ip6Range.split("-"); + vlanResponse.setStartIpv6(range[0]); + vlanResponse.setEndIpv6(range[1]); } if (vlan.getNetworkId() != null) { @@ -683,7 +684,7 @@ public class ApiResponseHelper implements ResponseGenerator { } } - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -723,7 +724,7 @@ public class ApiResponseHelper implements ResponseGenerator { lbResponse.setZoneId(zone.getUuid()); } - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.UserVm, loadBalancer.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -788,7 +789,8 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); } if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() + / (float) capacityResponse.getCapacityTotal() * 100f)); } else { capacityResponse.setPercentUsed(s_percentFormat.format(0L)); } @@ -808,7 +810,7 @@ public class ApiResponseHelper implements ResponseGenerator { return ApiDBUtils.newDataCenterResponse(vOffering, showCapacities); } - public static List getDataCenterCapacityResponse(Long zoneId){ + public static List getDataCenterCapacityResponse(Long zoneId) { List capacities = ApiDBUtils.getCapacityByClusterPodZone(zoneId, null, null); Set capacityResponses = new HashSet(); float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); @@ -827,7 +829,8 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); } if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() + / (float) capacityResponse.getCapacityTotal() * 100f)); } else { capacityResponse.setPercentUsed(s_percentFormat.format(0L)); } @@ -853,7 +856,8 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setCapacityUsed(capacity.getUsedCapacity()); capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() + / (float) capacityResponse.getCapacityTotal() * 100f)); } else { capacityResponse.setPercentUsed(s_percentFormat.format(0L)); } @@ -878,31 +882,26 @@ public class ApiResponseHelper implements ResponseGenerator { } - - @Override public StoragePoolResponse createStoragePoolResponse(StoragePool pool) { List viewPools = ApiDBUtils.newStoragePoolView(pool); - List listPools = ViewResponseHelper.createStoragePoolResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()])); + List listPools = ViewResponseHelper + .createStoragePoolResponse(viewPools.toArray(new StoragePoolJoinVO[viewPools.size()])); assert listPools != null && listPools.size() == 1 : "There should be one storage pool returned"; return listPools.get(0); - } - @Override public ImageStoreResponse createImageStoreResponse(ImageStore os) { List viewStores = ApiDBUtils.newImageStoreView(os); - List listStores = ViewResponseHelper.createImageStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()])); + List listStores = ViewResponseHelper + .createImageStoreResponse(viewStores.toArray(new ImageStoreJoinVO[viewStores.size()])); assert listStores != null && listStores.size() == 1 : "There should be one image data store returned"; return listStores.get(0); - } - - @Override public ClusterResponse createClusterResponse(Cluster cluster, Boolean showCapacities) { ClusterResponse clusterResponse = new ClusterResponse(); @@ -922,12 +921,11 @@ public class ApiResponseHelper implements ResponseGenerator { clusterResponse.setClusterType(cluster.getClusterType().toString()); clusterResponse.setAllocationState(cluster.getAllocationState().toString()); clusterResponse.setManagedState(cluster.getManagedState().toString()); - String cpuOvercommitRatio=ApiDBUtils.findClusterDetails(cluster.getId(),"cpuOvercommitRatio").getValue(); - String memoryOvercommitRatio=ApiDBUtils.findClusterDetails(cluster.getId(),"memoryOvercommitRatio").getValue(); + String cpuOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "cpuOvercommitRatio").getValue(); + String memoryOvercommitRatio = ApiDBUtils.findClusterDetails(cluster.getId(), "memoryOvercommitRatio").getValue(); clusterResponse.setCpuovercommitratio(cpuOvercommitRatio); clusterResponse.setRamovercommitratio(memoryOvercommitRatio); - if (showCapacities != null && showCapacities) { List capacities = ApiDBUtils.getCapacityByClusterPodZone(null, null, cluster.getId()); Set capacityResponses = new HashSet(); @@ -939,10 +937,9 @@ public class ApiResponseHelper implements ResponseGenerator { if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_CPU) { capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * Float.parseFloat(cpuOvercommitRatio)))); - }else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_MEMORY){ + } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_MEMORY) { capacityResponse.setCapacityTotal(new Long((long) (capacity.getTotalCapacity() * Float.parseFloat(memoryOvercommitRatio)))); - } - else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { + } else if (capacity.getCapacityType() == Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED) { List c = ApiDBUtils.findNonSharedStorageForClusterPodZone(null, null, cluster.getId()); capacityResponse.setCapacityTotal(capacity.getTotalCapacity() - c.get(0).getTotalCapacity()); capacityResponse.setCapacityUsed(capacity.getUsedCapacity() - c.get(0).getUsedCapacity()); @@ -950,7 +947,8 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setCapacityTotal(capacity.getTotalCapacity()); } if (capacityResponse.getCapacityTotal() != 0) { - capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() / (float) capacityResponse.getCapacityTotal() * 100f)); + capacityResponse.setPercentUsed(s_percentFormat.format((float) capacityResponse.getCapacityUsed() + / (float) capacityResponse.getCapacityTotal() * 100f)); } else { capacityResponse.setPercentUsed(s_percentFormat.format(0L)); } @@ -999,7 +997,7 @@ public class ApiResponseHelper implements ResponseGenerator { stateToSet = "Deleting"; } - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PortForwardingRule, fwRule.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -1062,8 +1060,6 @@ public class ApiResponseHelper implements ResponseGenerator { return ViewResponseHelper.createUserVmResponse(objectName, viewVms.toArray(new UserVmJoinVO[viewVms.size()])); } - - @Override public DomainRouterResponse createDomainRouterResponse(VirtualRouter router) { List viewVrs = ApiDBUtils.newDomainRouterView(router); @@ -1072,26 +1068,25 @@ public class ApiResponseHelper implements ResponseGenerator { return listVrs.get(0); } - @Override public SystemVmResponse createSystemVmResponse(VirtualMachine vm) { SystemVmResponse vmResponse = new SystemVmResponse(); if (vm.getType() == Type.SecondaryStorageVm || vm.getType() == Type.ConsoleProxy) { // SystemVm vm = (SystemVm) systemVM; vmResponse.setId(vm.getUuid()); - //vmResponse.setObjectId(vm.getId()); + // vmResponse.setObjectId(vm.getId()); vmResponse.setSystemVmType(vm.getType().toString().toLowerCase()); vmResponse.setName(vm.getHostName()); - if ( vm.getPodIdToDeployIn() != null ){ + if (vm.getPodIdToDeployIn() != null) { HostPodVO pod = ApiDBUtils.findPodById(vm.getPodIdToDeployIn()); - if ( pod != null ){ - vmResponse.setPodId(pod.getUuid()); + if (pod != null) { + vmResponse.setPodId(pod.getUuid()); } } VMTemplateVO template = ApiDBUtils.findTemplateById(vm.getTemplateId()); - if (template != null){ - vmResponse.setTemplateId(template.getUuid()); + if (template != null) { + vmResponse.setTemplateId(template.getUuid()); } vmResponse.setCreated(vm.getCreated()); @@ -1215,267 +1210,45 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public TemplateResponse createIsoResponse(VirtualMachineTemplate result) { - TemplateResponse response = new TemplateResponse(); - response.setId(result.getUuid()); - response.setName(result.getName()); - response.setDisplayText(result.getDisplayText()); - response.setPublic(result.isPublicTemplate()); - response.setCreated(result.getCreated()); - response.setFormat(result.getFormat()); - GuestOS os = ApiDBUtils.findGuestOSById(result.getGuestOSId()); - if (os != null) { - response.setOsTypeId(os.getUuid()); - response.setOsTypeName(os.getDisplayName()); - } - response.setDetails(result.getDetails()); - Account caller = UserContext.current().getCaller(); + public TemplateResponse createTemplateUpdateResponse(VirtualMachineTemplate result) { + List tvo = ApiDBUtils.newTemplateView(result); + List listVrs = ViewResponseHelper.createTemplateUpdateResponse(tvo.toArray(new TemplateJoinVO[tvo.size()])); + assert listVrs != null && listVrs.size() == 1 : "There should be one template returned"; + return listVrs.get(0); + } - if (result.getFormat() == ImageFormat.ISO) { // Templates are always bootable - response.setBootable(result.isBootable()); + @Override + public List createTemplateResponses(VirtualMachineTemplate result, Long zoneId, boolean readyOnly) { + List tvo = null; + if (zoneId == null || zoneId == -1) { + tvo = ApiDBUtils.newTemplateView(result); } else { - response.setHypervisor(result.getHypervisorType().toString());// hypervisors are associated with templates + tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly); + } - - // add account ID and name - Account owner = ApiDBUtils.findAccountById(result.getAccountId()); - populateAccount(response, owner.getId()); - populateDomain(response, owner.getDomainId()); - - //set tag information - List tags = null; - if (result.getFormat() == ImageFormat.ISO) { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, result.getId()); - } else { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, result.getId()); - } - - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - response.setTags(tagResponses); - - response.setObjectName("iso"); - return response; + return ViewResponseHelper.createTemplateResponse(tvo.toArray(new TemplateJoinVO[tvo.size()])); } @Override public List createTemplateResponses(long templateId, Long zoneId, boolean readyOnly) { - if (zoneId == null || zoneId == -1) { - List responses = new ArrayList(); - List dcs = new ArrayList(); - responses = createSwiftTemplateResponses(templateId); - if (!responses.isEmpty()) { - return responses; - } - dcs.addAll(ApiDBUtils.listZones()); - for (DataCenterVO dc : dcs) { - responses.addAll(createTemplateResponses(templateId, dc.getId(), readyOnly)); - } - return responses; - } else { - return createTemplateResponses(templateId, zoneId.longValue(), readyOnly); - } - } - - private List createSwiftTemplateResponses(long templateId) { VirtualMachineTemplate template = findTemplateById(templateId); - List responses = new ArrayList(); - VMTemplateSwiftVO templateSwiftRef = ApiDBUtils.findTemplateSwiftRef(templateId); - if (templateSwiftRef == null) { - return responses; - } - - TemplateResponse templateResponse = new TemplateResponse(); - templateResponse.setId(template.getUuid()); - templateResponse.setName(template.getName()); - templateResponse.setDisplayText(template.getDisplayText()); - templateResponse.setPublic(template.isPublicTemplate()); - templateResponse.setCreated(templateSwiftRef.getCreated()); - - templateResponse.setReady(true); - templateResponse.setFeatured(template.isFeatured()); - templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); - templateResponse.setPasswordEnabled(template.getEnablePassword()); - templateResponse.setSshKeyEnabled(template.getEnableSshKey()); - templateResponse.setCrossZones(template.isCrossZones()); - templateResponse.setFormat(template.getFormat()); - templateResponse.setDetails(template.getDetails()); - if (template.getTemplateType() != null) { - templateResponse.setTemplateType(template.getTemplateType().toString()); - } - - templateResponse.setHypervisor(template.getHypervisorType().toString()); - - GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId()); - if (os != null) { - templateResponse.setOsTypeId(os.getUuid()); - templateResponse.setOsTypeName(os.getDisplayName()); - } else { - templateResponse.setOsTypeId("-1"); - templateResponse.setOsTypeName(""); - } - - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(template.getAccountId()); - populateAccount(templateResponse, account.getId()); - populateDomain(templateResponse, account.getDomainId()); - - Account caller = UserContext.current().getCaller(); - boolean isAdmin = false; - if (BaseCmd.isAdmin(caller.getType())) { - isAdmin = true; - } - - // If the user is an Admin, add the template download status - if (isAdmin || caller.getId() == template.getAccountId()) { - // add download status - templateResponse.setStatus("Successfully Installed"); - } - - Long templateSize = templateSwiftRef.getSize(); - if (templateSize > 0) { - templateResponse.setSize(templateSize); - } - - templateResponse.setChecksum(template.getChecksum()); - if (template.getSourceTemplateId() != null) { - VirtualMachineTemplate tmpl = ApiDBUtils.findTemplateById(template.getSourceTemplateId()); - if (tmpl != null) { - templateResponse.setSourceTemplateId(tmpl.getUuid()); - } - } - - templateResponse.setChecksum(template.getChecksum()); - - templateResponse.setTemplateTag(template.getTemplateTag()); - - templateResponse.setObjectName("template"); - responses.add(templateResponse); - return responses; + return createTemplateResponses(template, zoneId, readyOnly); } + @Override - public List createTemplateResponses(long templateId, long zoneId, boolean readyOnly) { - VirtualMachineTemplate template = findTemplateById(templateId); - List responses = new ArrayList(); - VMTemplateHostVO templateHostRef = ApiDBUtils.findTemplateHostRef(templateId, zoneId, readyOnly); - if (templateHostRef == null) { - return responses; - } - - HostVO host = ApiDBUtils.findHostById(templateHostRef.getHostId()); - if (host.getType() == Host.Type.LocalSecondaryStorage && host.getStatus() != com.cloud.host.Status.Up) { - return responses; - } - - TemplateResponse templateResponse = new TemplateResponse(); - templateResponse.setId(template.getUuid()); - templateResponse.setName(template.getName()); - templateResponse.setDisplayText(template.getDisplayText()); - templateResponse.setPublic(template.isPublicTemplate()); - templateResponse.setCreated(templateHostRef.getCreated()); - - templateResponse.setReady(templateHostRef.getDownloadState() == Status.DOWNLOADED); - templateResponse.setFeatured(template.isFeatured()); - templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); - templateResponse.setPasswordEnabled(template.getEnablePassword()); - templateResponse.setSshKeyEnabled(template.getEnableSshKey()); - templateResponse.setCrossZones(template.isCrossZones()); - templateResponse.setFormat(template.getFormat()); - if (template.getTemplateType() != null) { - templateResponse.setTemplateType(template.getTemplateType().toString()); - } - - templateResponse.setHypervisor(template.getHypervisorType().toString()); - templateResponse.setDetails(template.getDetails()); - - GuestOS os = ApiDBUtils.findGuestOSById(template.getGuestOSId()); - if (os != null) { - templateResponse.setOsTypeId(os.getUuid()); - templateResponse.setOsTypeName(os.getDisplayName()); + public List createIsoResponses(VirtualMachineTemplate result, Long zoneId, boolean readyOnly) { + List tvo = null; + if (zoneId == null || zoneId == -1) { + tvo = ApiDBUtils.newTemplateView(result); } else { - templateResponse.setOsTypeId("-1"); - templateResponse.setOsTypeName(""); + tvo = ApiDBUtils.newTemplateView(result, zoneId, readyOnly); + } - - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(template.getAccountId()); - populateAccount(templateResponse, account.getId()); - populateDomain(templateResponse, account.getDomainId()); - - DataCenter datacenter = ApiDBUtils.findZoneById(zoneId); - - if (datacenter != null) { - // Add the zone ID - templateResponse.setZoneId(datacenter.getUuid()); - templateResponse.setZoneName(datacenter.getName()); - } - - boolean isAdmin = false; - Account caller = UserContext.current().getCaller(); - if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { - isAdmin = true; - } - - // If the user is an Admin, add the template download status - if (isAdmin || caller.getId() == template.getAccountId()) { - // add download status - if (templateHostRef.getDownloadState() != Status.DOWNLOADED) { - String templateStatus = "Processing"; - if (templateHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { - if (templateHostRef.getDownloadPercent() == 100) { - templateStatus = "Installing Template"; - } else { - templateStatus = templateHostRef.getDownloadPercent() + "% Downloaded"; - } - } else { - templateStatus = templateHostRef.getErrorString(); - } - templateResponse.setStatus(templateStatus); - } else if (templateHostRef.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { - templateResponse.setStatus("Download Complete"); - } else { - templateResponse.setStatus("Successfully Installed"); - } - } - - Long templateSize = templateHostRef.getSize(); - if (templateSize > 0) { - templateResponse.setSize(templateSize); - } - - templateResponse.setChecksum(template.getChecksum()); - if (template.getSourceTemplateId() != null) { - VirtualMachineTemplate tmpl = ApiDBUtils.findTemplateById(template.getSourceTemplateId()); - if (tmpl != null) { - templateResponse.setSourceTemplateId(tmpl.getUuid()); - } - } - - templateResponse.setChecksum(template.getChecksum()); - - templateResponse.setTemplateTag(template.getTemplateTag()); - - //set tag information - List tags = null; - if (template.getFormat() == ImageFormat.ISO) { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, template.getId()); - } else { - tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Template, template.getId()); - } - List tagResponses = new ArrayList(); - for (ResourceTag tag : tags) { - ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); - tagResponses.add(tagResponse); - } - templateResponse.setTags(tagResponses); - - templateResponse.setObjectName("template"); - responses.add(templateResponse); - return responses; + return ViewResponseHelper.createIsoResponse(tvo.toArray(new TemplateJoinVO[tvo.size()])); } + /* @Override public List createIsoResponses(long isoId, Long zoneId, boolean readyOnly) { @@ -1503,8 +1276,8 @@ public class ApiResponseHelper implements ResponseGenerator { populateAccount(isoResponse, owner.getId()); populateDomain(isoResponse, owner.getDomainId()); - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); + // set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { ResourceTagResponse tagResponse = createResourceTagResponse(tag, true); @@ -1727,8 +1500,8 @@ public class ApiResponseHelper implements ResponseGenerator { isoResponse.setSize(isoSize); } - //set tag information - List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); + // set tag information + List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.ISO, iso.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -1741,8 +1514,7 @@ public class ApiResponseHelper implements ResponseGenerator { isoResponses.add(isoResponse); return isoResponses; } - - +*/ @Override public SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group) { @@ -1806,8 +1578,6 @@ public class ApiResponseHelper implements ResponseGenerator { return createTemplateResponses(templateId, host.getDataCenterId(), true); } - - @Override public EventResponse createEventResponse(Event event) { EventJoinVO vEvent = ApiDBUtils.newEventView(event); @@ -1824,14 +1594,17 @@ public class ApiResponseHelper implements ResponseGenerator { List allStoragePools = ApiDBUtils.searchForStoragePools(c); for (StoragePoolVO pool : allStoragePools) { StoragePoolType poolType = pool.getPoolType(); - if (!(poolType.isShared())) {// All the non shared storages shouldn't show up in the capacity calculation + if (!(poolType.isShared())) {// All the non shared storages + // shouldn't show up in the capacity + // calculation poolIdsToIgnore.add(pool.getId()); } } float cpuOverprovisioningFactor = ApiDBUtils.getCpuOverprovisioningFactor(); - // collect all the capacity types, sum allocated/used and sum total...get one capacity number for each + // collect all the capacity types, sum allocated/used and sum + // total...get one capacity number for each for (Capacity capacity : hostCapacities) { // check if zone exist @@ -1991,10 +1764,11 @@ public class ApiResponseHelper implements ResponseGenerator { capacityResponse.setZoneId(zone.getUuid()); capacityResponse.setZoneName(zone.getName()); } - if (summedCapacity.getUsedPercentage() != null){ + if (summedCapacity.getUsedPercentage() != null) { capacityResponse.setPercentUsed(format.format(summedCapacity.getUsedPercentage() * 100f)); } else if (summedCapacity.getTotalCapacity() != 0) { - capacityResponse.setPercentUsed(format.format((float) summedCapacity.getUsedCapacity() / (float) summedCapacity.getTotalCapacity() * 100f)); + capacityResponse.setPercentUsed(format.format((float) summedCapacity.getUsedCapacity() / (float) summedCapacity.getTotalCapacity() + * 100f)); } else { capacityResponse.setPercentUsed(format.format(0L)); } @@ -2012,7 +1786,8 @@ public class ApiResponseHelper implements ResponseGenerator { VirtualMachineTemplate template = ApiDBUtils.findTemplateById(id); Account templateOwner = ApiDBUtils.findAccountById(template.getAccountId()); if (isAdmin) { - // FIXME: we have just template id and need to get template owner from that + // FIXME: we have just template id and need to get template owner + // from that if (templateOwner != null) { templateOwnerDomain = templateOwner.getDomainId(); } @@ -2193,10 +1968,10 @@ public class ApiResponseHelper implements ResponseGenerator { eLb.setValue(offering.getElasticLb() ? "true" : "false"); lbCapResponse.add(eLb); - CapabilityResponse inline = new CapabilityResponse(); - inline.setName(Capability.InlineMode.getName()); - inline.setValue(offering.isInline() ? "true" : "false"); - lbCapResponse.add(inline); + CapabilityResponse inline = new CapabilityResponse(); + inline.setName(Capability.InlineMode.getName()); + inline.setValue(offering.isInline() ? "true" : "false"); + lbCapResponse.add(inline); svcRsp.setCapabilities(lbCapResponse); } else if (Service.SourceNat == service) { @@ -2234,7 +2009,8 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public NetworkResponse createNetworkResponse(Network network) { - // need to get network profile in order to retrieve dns information from there + // need to get network profile in order to retrieve dns information from + // there NetworkProfile profile = ApiDBUtils.getNetworkProfile(network.getId()); NetworkResponse response = new NetworkResponse(); response.setId(network.getUuid()); @@ -2257,8 +2033,10 @@ public class ApiResponseHelper implements ResponseGenerator { // FIXME - either set netmask or cidr response.setCidr(network.getCidr()); response.setNetworkCidr((network.getNetworkCidr())); - // If network has reservation its entire network cidr is defined by getNetworkCidr() - // if no reservation is present then getCidr() will define the entire network cidr + // If network has reservation its entire network cidr is defined by + // getNetworkCidr() + // if no reservation is present then getCidr() will define the entire + // network cidr if (network.getNetworkCidr() != null) { response.setNetmask(NetUtils.cidr2Netmask(network.getNetworkCidr())); } @@ -2269,44 +2047,45 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIp6Gateway(network.getIp6Gateway()); response.setIp6Cidr(network.getIp6Cidr()); - // create response for reserved IP ranges that can be used for non-cloudstack purposes - String reservation = null; + // create response for reserved IP ranges that can be used for + // non-cloudstack purposes + String reservation = null; if ((network.getCidr() != null) && (NetUtils.isNetworkAWithinNetworkB(network.getCidr(), network.getNetworkCidr()))) { - String[] guestVmCidrPair = network.getCidr().split("\\/"); - String[] guestCidrPair = network.getNetworkCidr().split("\\/"); + String[] guestVmCidrPair = network.getCidr().split("\\/"); + String[] guestCidrPair = network.getNetworkCidr().split("\\/"); - Long guestVmCidrSize = Long.valueOf(guestVmCidrPair[1]); - Long guestCidrSize = Long.valueOf(guestCidrPair[1]); + Long guestVmCidrSize = Long.valueOf(guestVmCidrPair[1]); + Long guestCidrSize = Long.valueOf(guestCidrPair[1]); - String[] guestVmIpRange = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], guestVmCidrSize); - String[] guestIpRange = NetUtils.getIpRangeFromCidr(guestCidrPair[0], guestCidrSize); - long startGuestIp = NetUtils.ip2Long(guestIpRange[0]); - long endGuestIp = NetUtils.ip2Long(guestIpRange[1]); - long startVmIp = NetUtils.ip2Long(guestVmIpRange[0]); - long endVmIp = NetUtils.ip2Long(guestVmIpRange[1]); + String[] guestVmIpRange = NetUtils.getIpRangeFromCidr(guestVmCidrPair[0], guestVmCidrSize); + String[] guestIpRange = NetUtils.getIpRangeFromCidr(guestCidrPair[0], guestCidrSize); + long startGuestIp = NetUtils.ip2Long(guestIpRange[0]); + long endGuestIp = NetUtils.ip2Long(guestIpRange[1]); + long startVmIp = NetUtils.ip2Long(guestVmIpRange[0]); + long endVmIp = NetUtils.ip2Long(guestVmIpRange[1]); - if (startVmIp == startGuestIp && endVmIp < endGuestIp -1) { - reservation = (NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp)); - } - if (endVmIp == endGuestIp && startVmIp > startGuestIp + 1) { - reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp-1)); - } - if(startVmIp > startGuestIp + 1 && endVmIp < endGuestIp - 1) { - reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp-1) + " , " + - NetUtils.long2Ip(endVmIp + 1) + "-"+ NetUtils.long2Ip(endGuestIp)); + if (startVmIp == startGuestIp && endVmIp < endGuestIp - 1) { + reservation = (NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils.long2Ip(endGuestIp)); + } + if (endVmIp == endGuestIp && startVmIp > startGuestIp + 1) { + reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1)); + } + if (startVmIp > startGuestIp + 1 && endVmIp < endGuestIp - 1) { + reservation = (NetUtils.long2Ip(startGuestIp) + "-" + NetUtils.long2Ip(startVmIp - 1) + " , " + NetUtils.long2Ip(endVmIp + 1) + "-" + NetUtils + .long2Ip(endGuestIp)); } } response.setReservedIpRange(reservation); - //return vlan information only to Root admin + // return vlan information only to Root admin if (network.getBroadcastUri() != null && UserContext.current().getCaller().getType() == Account.ACCOUNT_TYPE_ADMIN) { String broadcastUri = network.getBroadcastUri().toString(); response.setBroadcastUri(broadcastUri); - String vlan="N/A"; + String vlan = "N/A"; if (broadcastUri.startsWith("vlan")) { vlan = broadcastUri.substring("vlan://".length(), broadcastUri.length()); } - //return vlan information only to Root admin + // return vlan information only to Root admin response.setVlan(vlan); } @@ -2410,7 +2189,7 @@ public class ApiResponseHelper implements ResponseGenerator { } response.setCanUseForDeploy(ApiDBUtils.canUseForDeploy(network)); - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Network, network.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -2441,9 +2220,6 @@ public class ApiResponseHelper implements ResponseGenerator { return listPrjs.get(0); } - - - @Override public FirewallResponse createFirewallResponse(FirewallRule fwRule) { FirewallResponse response = new FirewallResponse(); @@ -2479,7 +2255,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIcmpCode(fwRule.getIcmpCode()); response.setIcmpType(fwRule.getIcmpType()); - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.FirewallRule, fwRule.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -2523,7 +2299,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setState(stateToSet); - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.NetworkACL, networkACL.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -2547,7 +2323,8 @@ public class ApiResponseHelper implements ResponseGenerator { return hpvCapabilitiesResponse; } - // TODO: we may need to refactor once ControlledEntityResponse and ControlledEntity id to uuid conversion are all done. + // TODO: we may need to refactor once ControlledEntityResponse and + // ControlledEntity id to uuid conversion are all done. // currently code is scattered in private void populateOwner(ControlledEntityResponse response, ControlledEntity object) { Account account = ApiDBUtils.findAccountByIdIncludingRemoved(object.getAccountId()); @@ -2606,16 +2383,12 @@ public class ApiResponseHelper implements ResponseGenerator { return listProjs.get(0); } - - - @Override public ProjectInvitationResponse createProjectInvitationResponse(ProjectInvitation invite) { ProjectInvitationJoinVO vInvite = ApiDBUtils.newProjectInvitationView(invite); return ApiDBUtils.newProjectInvitationResponse(vInvite); } - @Override public SystemVmInstanceResponse createSystemVmInstanceResponse(VirtualMachine vm) { SystemVmInstanceResponse vmResponse = new SystemVmInstanceResponse(); @@ -2685,9 +2458,8 @@ public class ApiResponseHelper implements ResponseGenerator { CapabilityResponse capabilityResponse = new CapabilityResponse(); capabilityResponse.setName(cap.getName()); capabilityResponse.setObjectName("capability"); - if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || - cap.getName().equals(Capability.SupportedSourceNatTypes.getName()) || - cap.getName().equals(Capability.RedundantRouter.getName())) { + if (cap.getName().equals(Capability.SupportedLBIsolation.getName()) || cap.getName().equals(Capability.SupportedSourceNatTypes.getName()) + || cap.getName().equals(Capability.RedundantRouter.getName())) { capabilityResponse.setCanChoose(true); } else { capabilityResponse.setCanChoose(false); @@ -2700,7 +2472,8 @@ public class ApiResponseHelper implements ResponseGenerator { List serviceProviders = ApiDBUtils.getProvidersForService(service); List serviceProvidersResponses = new ArrayList(); for (Network.Provider serviceProvider : serviceProviders) { - // return only Virtual Router/JuniperSRX as a provider for the firewall + // return only Virtual Router/JuniperSRX as a provider for the + // firewall if (service == Service.Firewall && !(serviceProvider == Provider.VirtualRouter || serviceProvider == Provider.JuniperSRX)) { continue; } @@ -2784,8 +2557,7 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public LBStickinessResponse createLBStickinessPolicyResponse( - StickinessPolicy stickinessPolicy, LoadBalancer lb) { + public LBStickinessResponse createLBStickinessPolicyResponse(StickinessPolicy stickinessPolicy, LoadBalancer lb) { LBStickinessResponse spResponse = new LBStickinessResponse(); spResponse.setlbRuleId(lb.getUuid()); @@ -2800,8 +2572,7 @@ public class ApiResponseHelper implements ResponseGenerator { } List responses = new ArrayList(); - LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse( - stickinessPolicy); + LBStickinessPolicyResponse ruleResponse = new LBStickinessPolicyResponse(stickinessPolicy); responses.add(ruleResponse); spResponse.setRules(responses); @@ -2811,8 +2582,7 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public LBStickinessResponse createLBStickinessPolicyResponse( - List stickinessPolicies, LoadBalancer lb) { + public LBStickinessResponse createLBStickinessPolicyResponse(List stickinessPolicies, LoadBalancer lb) { LBStickinessResponse spResponse = new LBStickinessResponse(); if (lb == null) @@ -2840,8 +2610,7 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public LBHealthCheckResponse createLBHealthCheckPolicyResponse( - List healthcheckPolicies, LoadBalancer lb) { + public LBHealthCheckResponse createLBHealthCheckPolicyResponse(List healthcheckPolicies, LoadBalancer lb) { LBHealthCheckResponse hcResponse = new LBHealthCheckResponse(); if (lb == null) @@ -2892,9 +2661,8 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public LDAPConfigResponse createLDAPConfigResponse(String hostname, - Integer port, Boolean useSSL, String queryFilter, - String searchBase, String bindDN) { + public LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String searchBase, + String bindDN) { LDAPConfigResponse lr = new LDAPConfigResponse(); lr.setHostname(hostname); lr.setPort(port.toString()); @@ -2922,15 +2690,15 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } - @Override - public RegionResponse createRegionResponse(Region region) { - RegionResponse response = new RegionResponse(); - response.setId(region.getId()); - response.setName(region.getName()); - response.setEndPoint(region.getEndPoint()); - response.setObjectName("region"); - return response; - } + @Override + public RegionResponse createRegionResponse(Region region) { + RegionResponse response = new RegionResponse(); + response.setId(region.getId()); + response.setName(region.getName()); + response.setEndPoint(region.getEndPoint()); + response.setObjectName("region"); + return response; + } @Override public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) { @@ -2938,8 +2706,6 @@ public class ApiResponseHelper implements ResponseGenerator { return ApiDBUtils.newResourceTagResponse(rto, keyValueOnly); } - - @Override public VpcOfferingResponse createVpcOfferingResponse(VpcOffering offering) { VpcOfferingResponse response = new VpcOfferingResponse(); @@ -2975,7 +2741,6 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } - @Override public VpcResponse createVpcResponse(Vpc vpc) { VpcResponse response = new VpcResponse(); @@ -3030,7 +2795,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setServices(serviceResponses); populateOwner(response, vpc); - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.Vpc, vpc.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -3071,7 +2836,6 @@ public class ApiResponseHelper implements ResponseGenerator { response.setObjectName("privategateway"); - return response; } @@ -3216,7 +2980,7 @@ public class ApiResponseHelper implements ResponseGenerator { populateAccount(response, result.getAccountId()); populateDomain(response, result.getDomainId()); - //set tag information + // set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.StaticRoute, result.getId()); List tagResponses = new ArrayList(); for (ResourceTag tag : tags) { @@ -3275,7 +3039,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setId(result.getUuid()); Long vpnGatewayId = result.getVpnGatewayId(); - if(vpnGatewayId != null) { + if (vpnGatewayId != null) { Site2SiteVpnGateway vpnGateway = ApiDBUtils.findVpnGatewayById(vpnGatewayId); if (vpnGateway != null) { response.setVpnGatewayId(vpnGateway.getUuid()); @@ -3286,7 +3050,7 @@ public class ApiResponseHelper implements ResponseGenerator { } Long customerGatewayId = result.getCustomerGatewayId(); - if(customerGatewayId != null) { + if (customerGatewayId != null) { Site2SiteCustomerGateway customerGateway = ApiDBUtils.findCustomerGatewayById(customerGatewayId); if (customerGateway != null) { response.setCustomerGatewayId(customerGateway.getUuid()); @@ -3310,13 +3074,14 @@ public class ApiResponseHelper implements ResponseGenerator { response.setObjectName("vpnconnection"); return response; } + @Override public GuestOSResponse createGuestOSResponse(GuestOS guestOS) { GuestOSResponse response = new GuestOSResponse(); response.setDescription(guestOS.getDisplayName()); response.setId(guestOS.getUuid()); GuestOSCategoryVO category = ApiDBUtils.findGuestOsCategoryById(guestOS.getCategoryId()); - if ( category != null ){ + if (category != null) { response.setOsCategoryId(category.getUuid()); } @@ -3324,8 +3089,6 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } - - @Override public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) { SnapshotScheduleResponse response = new SnapshotScheduleResponse(); @@ -3348,172 +3111,171 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } + @Override + public UsageRecordResponse createUsageResponse(Usage usageRecord) { + UsageRecordResponse usageRecResponse = new UsageRecordResponse(); - @Override - public UsageRecordResponse createUsageResponse(Usage usageRecord) { - UsageRecordResponse usageRecResponse = new UsageRecordResponse(); + Account account = ApiDBUtils.findAccountByIdIncludingRemoved(usageRecord.getAccountId()); + if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { + // find the project + Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId()); + usageRecResponse.setProjectId(project.getUuid()); + usageRecResponse.setProjectName(project.getName()); + } else { + usageRecResponse.setAccountId(account.getUuid()); + usageRecResponse.setAccountName(account.getAccountName()); + } - Account account = ApiDBUtils.findAccountByIdIncludingRemoved(usageRecord.getAccountId()); - if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) { - //find the project - Project project = ApiDBUtils.findProjectByProjectAccountIdIncludingRemoved(account.getId()); - usageRecResponse.setProjectId(project.getUuid()); - usageRecResponse.setProjectName(project.getName()); - } else { - usageRecResponse.setAccountId(account.getUuid()); - usageRecResponse.setAccountName(account.getAccountName()); - } + Domain domain = ApiDBUtils.findDomainById(usageRecord.getDomainId()); + if (domain != null) { + usageRecResponse.setDomainId(domain.getUuid()); + } - Domain domain = ApiDBUtils.findDomainById(usageRecord.getDomainId()); - if (domain != null) { - usageRecResponse.setDomainId(domain.getUuid()); - } + if (usageRecord.getZoneId() != null) { + DataCenter zone = ApiDBUtils.findZoneById(usageRecord.getZoneId()); + if (zone != null) { + usageRecResponse.setZoneId(zone.getUuid()); + } + } + usageRecResponse.setDescription(usageRecord.getDescription()); + usageRecResponse.setUsage(usageRecord.getUsageDisplay()); + usageRecResponse.setUsageType(usageRecord.getUsageType()); + if (usageRecord.getVmInstanceId() != null) { + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId()); + usageRecResponse.setVirtualMachineId(vm.getUuid()); + } + usageRecResponse.setVmName(usageRecord.getVmName()); + if (usageRecord.getTemplateId() != null) { + VMTemplateVO template = ApiDBUtils.findTemplateById(usageRecord.getTemplateId()); + if (template != null) { + usageRecResponse.setTemplateId(template.getUuid()); + } + } - if (usageRecord.getZoneId() != null) { - DataCenter zone = ApiDBUtils.findZoneById(usageRecord.getZoneId()); - if (zone != null) { - usageRecResponse.setZoneId(zone.getUuid()); - } - } - usageRecResponse.setDescription(usageRecord.getDescription()); - usageRecResponse.setUsage(usageRecord.getUsageDisplay()); - usageRecResponse.setUsageType(usageRecord.getUsageType()); - if (usageRecord.getVmInstanceId() != null) { - VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getVmInstanceId()); - usageRecResponse.setVirtualMachineId(vm.getUuid()); - } - usageRecResponse.setVmName(usageRecord.getVmName()); - if (usageRecord.getTemplateId() != null) { - VMTemplateVO template = ApiDBUtils.findTemplateById(usageRecord.getTemplateId()); - if (template != null) { - usageRecResponse.setTemplateId(template.getUuid()); - } - } + if (usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM) { + ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString()); + // Service Offering Id + usageRecResponse.setOfferingId(svcOffering.getUuid()); + // VM Instance ID + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(vm.getUuid()); + // Hypervisor Type + usageRecResponse.setType(usageRecord.getType()); - if(usageRecord.getUsageType() == UsageTypes.RUNNING_VM || usageRecord.getUsageType() == UsageTypes.ALLOCATED_VM){ - ServiceOfferingVO svcOffering = _entityMgr.findByIdIncludingRemoved(ServiceOfferingVO.class, usageRecord.getOfferingId().toString()); - //Service Offering Id - usageRecResponse.setOfferingId(svcOffering.getUuid()); - //VM Instance ID - VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(vm.getUuid()); - //Hypervisor Type - usageRecResponse.setType(usageRecord.getType()); + } else if (usageRecord.getUsageType() == UsageTypes.IP_ADDRESS) { + // isSourceNAT + usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat")) ? true : false); + // isSystem + usageRecResponse.setSystem((usageRecord.getSize() == 1) ? true : false); + // IP Address ID + IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(ip.getUuid()); - } else if(usageRecord.getUsageType() == UsageTypes.IP_ADDRESS){ - //isSourceNAT - usageRecResponse.setSourceNat((usageRecord.getType().equals("SourceNat"))?true:false); - //isSystem - usageRecResponse.setSystem((usageRecord.getSize() == 1)?true:false); - //IP Address ID - IPAddressVO ip = _entityMgr.findByIdIncludingRemoved(IPAddressVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(ip.getUuid()); + } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) { + // Device Type + usageRecResponse.setType(usageRecord.getType()); + if (usageRecord.getType().equals("DomainRouter")) { + // Domain Router Id + VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(vm.getUuid()); + } else { + // External Device Host Id + HostVO host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(host.getUuid()); + } + // Network ID + NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString()); + usageRecResponse.setNetworkId(network.getUuid()); - } else if(usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED){ - //Device Type - usageRecResponse.setType(usageRecord.getType()); - if(usageRecord.getType().equals("DomainRouter")){ - //Domain Router Id - VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(vm.getUuid()); - } else { - //External Device Host Id - HostVO host = _entityMgr.findByIdIncludingRemoved(HostVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(host.getUuid()); - } - //Network ID - NetworkVO network = _entityMgr.findByIdIncludingRemoved(NetworkVO.class, usageRecord.getNetworkId().toString()); - usageRecResponse.setNetworkId(network.getUuid()); + } else if (usageRecord.getUsageType() == UsageTypes.VOLUME) { + // Volume ID + VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(volume.getUuid()); + // Volume Size + usageRecResponse.setSize(usageRecord.getSize()); + // Disk Offering Id + if (usageRecord.getOfferingId() != null) { + DiskOfferingVO diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString()); + usageRecResponse.setOfferingId(diskOff.getUuid()); + } - } else if(usageRecord.getUsageType() == UsageTypes.VOLUME){ - //Volume ID - VolumeVO volume = _entityMgr.findByIdIncludingRemoved(VolumeVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(volume.getUuid()); - //Volume Size - usageRecResponse.setSize(usageRecord.getSize()); - //Disk Offering Id - if(usageRecord.getOfferingId() != null){ - DiskOfferingVO diskOff = _entityMgr.findByIdIncludingRemoved(DiskOfferingVO.class, usageRecord.getOfferingId().toString()); - usageRecResponse.setOfferingId(diskOff.getUuid()); - } + } else if (usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO) { + // Template/ISO ID + VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(tmpl.getUuid()); + // Template/ISO Size + usageRecResponse.setSize(usageRecord.getSize()); - } else if(usageRecord.getUsageType() == UsageTypes.TEMPLATE || usageRecord.getUsageType() == UsageTypes.ISO){ - //Template/ISO ID - VMTemplateVO tmpl = _entityMgr.findByIdIncludingRemoved(VMTemplateVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(tmpl.getUuid()); - //Template/ISO Size - usageRecResponse.setSize(usageRecord.getSize()); + } else if (usageRecord.getUsageType() == UsageTypes.SNAPSHOT) { + // Snapshot ID + SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(snap.getUuid()); + // Snapshot Size + usageRecResponse.setSize(usageRecord.getSize()); - } else if(usageRecord.getUsageType() == UsageTypes.SNAPSHOT){ - //Snapshot ID - SnapshotVO snap = _entityMgr.findByIdIncludingRemoved(SnapshotVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(snap.getUuid()); - //Snapshot Size - usageRecResponse.setSize(usageRecord.getSize()); + } else if (usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY) { + // Load Balancer Policy ID + usageRecResponse.setUsageId(usageRecord.getUsageId().toString()); - } else if(usageRecord.getUsageType() == UsageTypes.LOAD_BALANCER_POLICY){ - //Load Balancer Policy ID - usageRecResponse.setUsageId(usageRecord.getUsageId().toString()); + } else if (usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE) { + // Port Forwarding Rule ID + usageRecResponse.setUsageId(usageRecord.getUsageId().toString()); - } else if(usageRecord.getUsageType() == UsageTypes.PORT_FORWARDING_RULE){ - //Port Forwarding Rule ID - usageRecResponse.setUsageId(usageRecord.getUsageId().toString()); + } else if (usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING) { + // Network Offering Id + NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString()); + usageRecResponse.setOfferingId(netOff.getUuid()); + // is Default + usageRecResponse.setDefault((usageRecord.getUsageId() == 1) ? true : false); - } else if(usageRecord.getUsageType() == UsageTypes.NETWORK_OFFERING){ - //Network Offering Id - NetworkOfferingVO netOff = _entityMgr.findByIdIncludingRemoved(NetworkOfferingVO.class, usageRecord.getOfferingId().toString()); - usageRecResponse.setOfferingId(netOff.getUuid()); - //is Default - usageRecResponse.setDefault((usageRecord.getUsageId() == 1)? true:false); + } else if (usageRecord.getUsageType() == UsageTypes.VPN_USERS) { + // VPN User ID + usageRecResponse.setUsageId(usageRecord.getUsageId().toString()); - } else if(usageRecord.getUsageType() == UsageTypes.VPN_USERS){ - //VPN User ID - usageRecResponse.setUsageId(usageRecord.getUsageId().toString()); + } else if (usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP) { + // Security Group Id + SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString()); + usageRecResponse.setUsageId(sg.getUuid()); + } - } else if(usageRecord.getUsageType() == UsageTypes.SECURITY_GROUP){ - //Security Group Id - SecurityGroupVO sg = _entityMgr.findByIdIncludingRemoved(SecurityGroupVO.class, usageRecord.getUsageId().toString()); - usageRecResponse.setUsageId(sg.getUuid()); - } + if (usageRecord.getRawUsage() != null) { + DecimalFormat decimalFormat = new DecimalFormat("###########.######"); + usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage())); + } - if (usageRecord.getRawUsage() != null) { - DecimalFormat decimalFormat = new DecimalFormat("###########.######"); - usageRecResponse.setRawUsage(decimalFormat.format(usageRecord.getRawUsage())); - } - - if (usageRecord.getStartDate() != null) { - usageRecResponse.setStartDate(getDateStringInternal(usageRecord.getStartDate())); - } - if (usageRecord.getEndDate() != null) { - usageRecResponse.setEndDate(getDateStringInternal(usageRecord.getEndDate())); - } - - return usageRecResponse; - } + if (usageRecord.getStartDate() != null) { + usageRecResponse.setStartDate(getDateStringInternal(usageRecord.getStartDate())); + } + if (usageRecord.getEndDate() != null) { + usageRecResponse.setEndDate(getDateStringInternal(usageRecord.getEndDate())); + } + return usageRecResponse; + } public String getDateStringInternal(Date inputDate) { - if (inputDate == null) return null; + if (inputDate == null) + return null; TimeZone tz = _usageSvc.getUsageTimezone(); Calendar cal = Calendar.getInstance(tz); cal.setTime(inputDate); StringBuffer sb = new StringBuffer(); - sb.append(cal.get(Calendar.YEAR)+"-"); + sb.append(cal.get(Calendar.YEAR) + "-"); int month = cal.get(Calendar.MONTH) + 1; if (month < 10) { sb.append("0" + month + "-"); } else { - sb.append(month+"-"); + sb.append(month + "-"); } int day = cal.get(Calendar.DAY_OF_MONTH); if (day < 10) { sb.append("0" + day); } else { - sb.append(""+day); + sb.append("" + day); } sb.append("'T'"); @@ -3522,38 +3284,40 @@ public class ApiResponseHelper implements ResponseGenerator { if (hour < 10) { sb.append("0" + hour + ":"); } else { - sb.append(hour+":"); + sb.append(hour + ":"); } int minute = cal.get(Calendar.MINUTE); if (minute < 10) { sb.append("0" + minute + ":"); } else { - sb.append(minute+":"); + sb.append(minute + ":"); } int seconds = cal.get(Calendar.SECOND); if (seconds < 10) { sb.append("0" + seconds); } else { - sb.append(""+seconds); + sb.append("" + seconds); } double offset = cal.get(Calendar.ZONE_OFFSET); if (tz.inDaylightTime(inputDate)) { - offset += (1.0*tz.getDSTSavings()); // add the timezone's DST value (typically 1 hour expressed in milliseconds) + offset += (1.0 * tz.getDSTSavings()); // add the timezone's DST + // value (typically 1 hour + // expressed in milliseconds) } - offset = offset / (1000d*60d*60d); - int hourOffset = (int)offset; + offset = offset / (1000d * 60d * 60d); + int hourOffset = (int) offset; double decimalVal = Math.abs(offset) - Math.abs(hourOffset); - int minuteOffset = (int)(decimalVal * 60); + int minuteOffset = (int) (decimalVal * 60); if (hourOffset < 0) { if (hourOffset > -10) { - sb.append("-0"+Math.abs(hourOffset)); + sb.append("-0" + Math.abs(hourOffset)); } else { - sb.append("-"+Math.abs(hourOffset)); + sb.append("-" + Math.abs(hourOffset)); } } else { if (hourOffset < 10) { @@ -3607,7 +3371,7 @@ public class ApiResponseHelper implements ResponseGenerator { List secondaryIps = ApiDBUtils.findNicSecondaryIps(result.getId()); if (secondaryIps != null) { List ipList = new ArrayList(); - for (NicSecondaryIpVO ip: secondaryIps) { + for (NicSecondaryIpVO ip : secondaryIps) { NicSecondaryIpResponse ipRes = new NicSecondaryIpResponse(); ipRes.setId(ip.getUuid()); ipRes.setIpAddr(ip.getIp4Address()); diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 4b4c86e2f4e..71a0f29d45c 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -16,9 +16,13 @@ // under the License. package com.cloud.api.query; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -27,6 +31,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.command.admin.host.ListHostsCmd; import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd; import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd; @@ -35,6 +40,7 @@ import org.apache.cloudstack.api.command.admin.user.ListUsersCmd; import org.apache.cloudstack.api.command.user.account.ListAccountsCmd; import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd; import org.apache.cloudstack.api.command.user.event.ListEventsCmd; +import org.apache.cloudstack.api.command.user.iso.ListIsosCmd; import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd; import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd; import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd; @@ -42,6 +48,7 @@ import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd; import org.apache.cloudstack.api.command.user.project.ListProjectsCmd; import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd; import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; +import org.apache.cloudstack.api.command.user.template.ListTemplatesCmd; import org.apache.cloudstack.api.command.user.vm.ListVMsCmd; import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; @@ -62,6 +69,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.SecurityGroupResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; +import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; @@ -85,6 +93,7 @@ import com.cloud.api.query.dao.ResourceTagJoinDao; import com.cloud.api.query.dao.SecurityGroupJoinDao; import com.cloud.api.query.dao.ServiceOfferingJoinDao; import com.cloud.api.query.dao.StoragePoolJoinDao; +import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.api.query.dao.UserAccountJoinDao; import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.dao.VolumeJoinDao; @@ -104,6 +113,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.SecurityGroupJoinVO; import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.api.query.vo.StoragePoolJoinVO; +import com.cloud.api.query.vo.TemplateJoinVO; import com.cloud.api.query.vo.UserAccountJoinVO; import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.VolumeJoinVO; @@ -127,12 +137,20 @@ import com.cloud.projects.Project; import com.cloud.projects.ProjectManager; import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; +import com.cloud.resource.ResourceManager; import com.cloud.server.Criteria; +import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.template.VirtualMachineTemplate.TemplateFilter; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.AccountVO; @@ -146,6 +164,7 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; import com.cloud.utils.db.SearchCriteria.Func; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.vm.DomainRouterVO; @@ -255,6 +274,15 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { @Inject private HighAvailabilityManager _haMgr; + @Inject + private VMTemplateDao _templateDao; + + @Inject + private TemplateJoinDao _templateJoinDao; + + @Inject + ResourceManager _resourceMgr; + /* (non-Javadoc) * @see com.cloud.api.query.QueryService#searchForUsers(org.apache.cloudstack.api.command.admin.user.ListUsersCmd) */ @@ -2419,5 +2447,298 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { return false; } + @Override + public ListResponse listTemplates(ListTemplatesCmd cmd) { + Pair, Integer> result = searchForTemplatesInternal(cmd); + ListResponse response = new ListResponse(); + + List templateResponses = ViewResponseHelper.createTemplateResponse(result.first().toArray(new TemplateJoinVO[result.first().size()])); + response.setResponses(templateResponses, result.second()); + return response; + } + + private Pair, Integer> searchForTemplatesInternal(ListTemplatesCmd cmd) { + TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); + Long id = cmd.getId(); + Map tags = cmd.getTags(); + Account caller = UserContext.current().getCaller(); + + boolean listAll = false; + if (templateFilter != null && templateFilter == TemplateFilter.all) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); + } + listAll = true; + } + + List permittedAccountIds = new ArrayList(); + Ternary domainIdRecursiveListProject = new Ternary( + cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, + listAll, false); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + List permittedAccounts = new ArrayList(); + for (Long accountId : permittedAccountIds) { + permittedAccounts.add(_accountMgr.getAccount(accountId)); + } + + boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured)); + HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); + + return searchForTemplatesInternal(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), + cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); + } + + private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, + Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, + List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { + VMTemplateVO template = null; + + // verify templateId parameter + if (templateId != null) { + template = _templateDao.findById(templateId); + if (template == null) { + throw new InvalidParameterValueException("Please specify a valid template ID."); + }// If ISO requested then it should be ISO. + if (isIso && template.getFormat() != ImageFormat.ISO) { + s_logger.error("Template Id " + templateId + " is not an ISO"); + InvalidParameterValueException ex = new InvalidParameterValueException("Specified Template Id is not an ISO"); + ex.addProxyObject(template, templateId, "templateId"); + throw ex; + }// If ISO not requested then it shouldn't be an ISO. + if (!isIso && template.getFormat() == ImageFormat.ISO) { + s_logger.error("Incorrect format of the template id " + templateId); + InvalidParameterValueException ex = new InvalidParameterValueException("Incorrect format " + template.getFormat() + + " of the specified template id"); + ex.addProxyObject(template, templateId, "templateId"); + throw ex; + } + + // if template is not public, perform permission check here + if (!template.isPublicTemplate() && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + Account owner = _accountMgr.getAccount(template.getAccountId()); + _accountMgr.checkAccess(caller, null, true, owner); + } + } + + DomainVO domain = null; + if (!permittedAccounts.isEmpty()) { + domain = _domainDao.findById(permittedAccounts.get(0).getDomainId()); + } else { + domain = _domainDao.findById(DomainVO.ROOT_DOMAIN); + } + + List hypers = null; + if (!isIso) { + hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + } + + Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); + isAscending = (isAscending == null ? true : isAscending); + Filter searchFilter = new Filter(TemplateJoinVO.class, "sort_key", isAscending, startIndex, pageSize); + SearchCriteria sc = _templateJoinDao.createSearchCriteria(); + + // add criteria for project or not + if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { + sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly){ + sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); + } + + // add criteria for domain path in case of domain admin + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && + (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); + } + + List relatedDomainIds = new ArrayList(); + List permittedAccountIds = new ArrayList(); + if (!permittedAccounts.isEmpty()) { + for (Account account : permittedAccounts) { + permittedAccountIds.add(account.getId()); + DomainVO accountDomain = _domainDao.findById(account.getDomainId()); + + // get all parent domain ID's all the way till root domain + DomainVO domainTreeNode = accountDomain; + relatedDomainIds.add(domainTreeNode.getId()); + while (domainTreeNode.getParent() != null ){ + domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); + relatedDomainIds.add(domainTreeNode.getId()); + } + + // get all child domain ID's + if (_accountMgr.isAdmin(account.getType()) ) { + List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); + for (DomainVO childDomain : allChildDomains) { + relatedDomainIds.add(childDomain.getId()); + } + } + } + } + + // add hypervisor criteria + if ( !hypers.isEmpty()){ + String[] relatedHypers = new String[hypers.size()]; + for (int i = 0; i < hypers.size(); i++){ + relatedHypers[i] = hypers.get(i).toString(); + } + sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers); + } + + // control different template filters + if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { + sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); + if ( templateFilter == TemplateFilter.featured){ + sc.addAnd("featured", SearchCriteria.Op.EQ, true); + } + else{ + sc.addAnd("featured", SearchCriteria.Op.EQ, false); + } + if (!permittedAccounts.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); + scc.addOr("domainId", SearchCriteria.Op.NULL); + sc.addAnd("domainId", SearchCriteria.Op.SC, scc); + + if (!_accountMgr.isAdmin(caller.getType())){ + // for non-root users, we should only show featured and community templates that they can see + sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + } + } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable ) { + if ( !permittedAccounts.isEmpty()){ + sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + sc.addAnd("accountId", SearchCriteria.Op.SC, scc); + } else if (templateFilter == TemplateFilter.executable ) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); + if ( !permittedAccounts.isEmpty()){ + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); + } + + // add tags criteria + if (tags != null && !tags.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + int count = 0; + for (String key : tags.keySet()) { + SearchCriteria scTag = _templateJoinDao.createSearchCriteria(); + scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); + scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); + if ( isIso){ + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.ISO); + } else { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.Template); + } + scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); + count++; + } + sc.addAnd("tagKey", SearchCriteria.Op.SC, scc); + } + + // other criteria + if (keyword != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + } else if (name != null) { + sc.addAnd("name", SearchCriteria.Op.EQ, name); + } + + if (isIso) { + sc.addAnd("format", SearchCriteria.Op.EQ, "ISO"); + + } else { + sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO"); + } + + if (!hyperType.equals(HypervisorType.None)) { + sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType); + } + + if (bootable != null) { + sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable); + } + + if (onlyReady){ + sc.addAnd("downlaadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); + sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); + } + + if (zoneId != null){ + sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); + } + + if (!showDomr){ + // excluding system template + sc.addAnd("type", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); + } + + // search unique templates and find details by Ids + Pair, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); + Integer count = uniqueTmplPair.second(); + if (count.intValue() == 0) { + // empty result + return uniqueTmplPair; + } + List uniqueTmpls = uniqueTmplPair.first(); + Long[] vrIds = new Long[uniqueTmpls.size()]; + int i = 0; + for (TemplateJoinVO v : uniqueTmpls) { + vrIds[i++] = v.getId(); + } + List vrs = _templateJoinDao.searchByIds(vrIds); + return new Pair, Integer>(vrs, count); + + //TODO: revisit the special logic for iso search in VMTemplateDaoImpl.searchForTemplates and understand why we need to + //specially handle ISO. The original logic is very twisted and no idea about what the code was doing. + + } + + @Override + public ListResponse listIsos(ListIsosCmd cmd) { + Pair, Integer> result = searchForIsosInternal(cmd); + ListResponse response = new ListResponse(); + + List templateResponses = ViewResponseHelper.createIsoResponse(result.first().toArray(new TemplateJoinVO[result.first().size()])); + response.setResponses(templateResponses, result.second()); + return response; + } + + private Pair, Integer> searchForIsosInternal(ListIsosCmd cmd) { + TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter()); + Long id = cmd.getId(); + Map tags = cmd.getTags(); + Account caller = UserContext.current().getCaller(); + + boolean listAll = false; + if (isoFilter != null && isoFilter == TemplateFilter.all) { + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { + throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); + } + listAll = true; + } + + List permittedAccountIds = new ArrayList(); + Ternary domainIdRecursiveListProject = new Ternary( + cmd.getDomainId(), cmd.isRecursive(), null); + _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, + listAll, false); + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + List permittedAccounts = new ArrayList(); + for (Long accountId : permittedAccountIds) { + permittedAccounts.add(_accountMgr.getAccount(accountId)); + } + + HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); + + return searchForTemplatesInternal(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), + cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, + listProjectResourcesCriteria, tags); + } } diff --git a/server/src/com/cloud/api/query/ViewResponseHelper.java b/server/src/com/cloud/api/query/ViewResponseHelper.java index 5b3c9346d9b..8ac99d23a86 100644 --- a/server/src/com/cloud/api/query/ViewResponseHelper.java +++ b/server/src/com/cloud/api/query/ViewResponseHelper.java @@ -38,6 +38,7 @@ import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.SecurityGroupResponse; import org.apache.cloudstack.api.response.ServiceOfferingResponse; import org.apache.cloudstack.api.response.StoragePoolResponse; +import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.UserResponse; import org.apache.cloudstack.api.response.UserVmResponse; import org.apache.cloudstack.api.response.VolumeResponse; @@ -61,6 +62,7 @@ import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.SecurityGroupJoinVO; import com.cloud.api.query.vo.ServiceOfferingJoinVO; import com.cloud.api.query.vo.StoragePoolJoinVO; +import com.cloud.api.query.vo.TemplateJoinVO; import com.cloud.api.query.vo.UserAccountJoinVO; import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.api.query.vo.VolumeJoinVO; @@ -323,4 +325,55 @@ public class ViewResponseHelper { } return respList; } + + public static List createTemplateResponse(TemplateJoinVO... templates) { + Hashtable vrDataList = new Hashtable(); + for (TemplateJoinVO vr : templates) { + TemplateResponse vrData = vrDataList.get(vr.getId()); + if ( vrData == null ){ + // first time encountering this volume + vrData = ApiDBUtils.newTemplateResponse(vr); + } + else{ + // update tags + vrData = ApiDBUtils.fillTemplateDetails(vrData, vr); + } + vrDataList.put(vr.getId(), vrData); + } + return new ArrayList(vrDataList.values()); + } + + public static List createTemplateUpdateResponse(TemplateJoinVO... templates) { + Hashtable vrDataList = new Hashtable(); + for (TemplateJoinVO vr : templates) { + TemplateResponse vrData = vrDataList.get(vr.getId()); + if ( vrData == null ){ + // first time encountering this volume + vrData = ApiDBUtils.newTemplateUpdateResponse(vr); + } + else{ + // update tags + vrData = ApiDBUtils.fillTemplateDetails(vrData, vr); + } + vrDataList.put(vr.getId(), vrData); + } + return new ArrayList(vrDataList.values()); + } + + public static List createIsoResponse(TemplateJoinVO... templates) { + Hashtable vrDataList = new Hashtable(); + for (TemplateJoinVO vr : templates) { + TemplateResponse vrData = vrDataList.get(vr.getId()); + if ( vrData == null ){ + // first time encountering this volume + vrData = ApiDBUtils.newIsoResponse(vr); + } + else{ + // update tags + vrData = ApiDBUtils.fillTemplateDetails(vrData, vr); + } + vrDataList.put(vr.getId(), vrData); + } + return new ArrayList(vrDataList.values()); + } } diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDao.java b/server/src/com/cloud/api/query/dao/TemplateJoinDao.java new file mode 100644 index 00000000000..3897db54746 --- /dev/null +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDao.java @@ -0,0 +1,42 @@ +// 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.api.query.dao; + +import java.util.List; + +import org.apache.cloudstack.api.response.TemplateResponse; +import com.cloud.api.query.vo.TemplateJoinVO; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.utils.db.GenericDao; + +public interface TemplateJoinDao extends GenericDao { + + TemplateResponse newTemplateResponse(TemplateJoinVO tmpl); + + TemplateResponse newIsoResponse(TemplateJoinVO tmpl); + + TemplateResponse newUpdateResponse(TemplateJoinVO tmpl); + + TemplateResponse setTemplateResponse(TemplateResponse tmplData, TemplateJoinVO tmpl); + + List newTemplateView(VirtualMachineTemplate tmpl); + + List newTemplateView(VirtualMachineTemplate tmpl, long zoneId, boolean readyOnly); + + List searchByIds(Long... ids); + + } diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java new file mode 100644 index 00000000000..0e5001be098 --- /dev/null +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -0,0 +1,441 @@ +// 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.api.query.dao; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; +import javax.inject.Inject; + +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.response.ResourceTagResponse; +import org.apache.cloudstack.api.response.TemplateResponse; +import org.apache.cloudstack.api.response.TemplateZoneResponse; +import org.apache.cloudstack.api.response.VolumeResponse; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.api.ApiDBUtils; +import com.cloud.api.ApiResponseHelper; +import com.cloud.api.query.vo.ResourceTagJoinVO; +import com.cloud.api.query.vo.TemplateJoinVO; +import com.cloud.api.query.vo.VolumeJoinVO; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.DataCenter; +import com.cloud.offering.ServiceOffering; +import com.cloud.server.ResourceTag; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.storage.GuestOS; +import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateHostVO; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.Volume; +import com.cloud.template.VirtualMachineTemplate; +import com.cloud.user.Account; +import com.cloud.user.UserContext; +import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; + + +@Component +@Local(value={TemplateJoinDao.class}) +public class TemplateJoinDaoImpl extends GenericDaoBase implements TemplateJoinDao { + + + + public static final Logger s_logger = Logger.getLogger(TemplateJoinDaoImpl.class); + + @Inject + private ConfigurationDao _configDao; + + private final SearchBuilder tmpltSearch; + + private final SearchBuilder tmpltIdSearch; + + private final SearchBuilder tmpltZoneSearch; + + + protected TemplateJoinDaoImpl() { + + tmpltSearch = createSearchBuilder(); + tmpltSearch.and("idIN", tmpltSearch.entity().getId(), SearchCriteria.Op.IN); + tmpltSearch.done(); + + tmpltIdSearch = createSearchBuilder(); + tmpltIdSearch.and("id", tmpltIdSearch.entity().getId(), SearchCriteria.Op.EQ); + tmpltIdSearch.done(); + + tmpltZoneSearch = createSearchBuilder(); + tmpltZoneSearch.and("id", tmpltZoneSearch.entity().getId(), SearchCriteria.Op.EQ); + tmpltZoneSearch.and("dataCenterId", tmpltZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + tmpltZoneSearch.and("downloadState", tmpltZoneSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); + tmpltZoneSearch.done(); + + // select distinct pair (template_id, zone_id) + this._count = "select count(distinct id) from template_view WHERE "; + } + + + + + @Override + public TemplateResponse newTemplateResponse(TemplateJoinVO template) { + TemplateResponse templateResponse = new TemplateResponse(); + templateResponse.setId(template.getUuid()); + templateResponse.setName(template.getName()); + templateResponse.setDisplayText(template.getDisplayText()); + templateResponse.setPublic(template.isPublicTemplate()); + templateResponse.setCreated(template.getCreatedOnStore()); + templateResponse.setReady(template.getDownloadState() == Status.DOWNLOADED); + templateResponse.setFeatured(template.isFeatured()); + templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); + templateResponse.setPasswordEnabled(template.isEnablePassword()); + templateResponse.setSshKeyEnabled(template.isEnableSshKey()); + templateResponse.setCrossZones(template.isCrossZones()); + templateResponse.setFormat(template.getFormat()); + if (template.getTemplateType() != null) { + templateResponse.setTemplateType(template.getTemplateType().toString()); + } + + templateResponse.setHypervisor(template.getHypervisorType().toString()); + + + templateResponse.setOsTypeId(template.getGuestOSUuid()); + templateResponse.setOsTypeName(template.getGuestOSName()); + + // populate owner. + ApiResponseHelper.populateOwner(templateResponse, template); + + // populate domain + templateResponse.setDomainId(template.getDomainUuid()); + templateResponse.setDomainName(template.getDomainName()); + + + + boolean isAdmin = false; + Account caller = UserContext.current().getCaller(); + if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { + isAdmin = true; + } + + // If the user is an Admin, add the template download status + if (isAdmin || caller.getId() == template.getAccountId()) { + // add download status + if (template.getDownloadState() != Status.DOWNLOADED) { + String templateStatus = "Processing"; + if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { + if (template.getDownloadPercent() == 100) { + templateStatus = "Installing Template"; + } else { + templateStatus = template.getDownloadPercent() + "% Downloaded"; + } + } else { + templateStatus = template.getErrorString(); + } + templateResponse.setStatus(templateStatus); + } else if (template.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { + templateResponse.setStatus("Download Complete"); + } else { + templateResponse.setStatus("Successfully Installed"); + } + } + + Long templateSize = template.getSize(); + if (templateSize > 0) { + templateResponse.setSize(templateSize); + } + + templateResponse.setChecksum(template.getChecksum()); + if (template.getSourceTemplateId() != null) { + templateResponse.setSourceTemplateId(template.getSourceTemplateUuid()); + } + templateResponse.setTemplateTag(template.getTemplateTag()); + + // set template zone information + if (template.getDataCenterId() > 0 ){ + TemplateZoneResponse tmplZoneResp = new TemplateZoneResponse(template.getDataCenterUuid(), template.getDataCenterName()); + templateResponse.addZone(tmplZoneResp); + // set the first found associated zone directly in TemplateResponse + templateResponse.setZoneId(template.getDataCenterUuid()); + templateResponse.setZoneName(template.getDataCenterName()); + } + + // set details map + if (template.getDetailName() != null){ + Map details = new HashMap(); + details.put(template.getDetailName(), template.getDetailValue()); + templateResponse.setDetails(details); + } + + // update tag information + long tag_id = template.getTagId(); + if (tag_id > 0) { + ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); + if ( vtag != null ){ + templateResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); + } + } + + + templateResponse.setObjectName("template"); + return templateResponse; + } + + + //TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse + // compared to listTemplates and listIsos. + @Override + public TemplateResponse newUpdateResponse(TemplateJoinVO result) { + TemplateResponse response = new TemplateResponse(); + response.setId(result.getUuid()); + response.setName(result.getName()); + response.setDisplayText(result.getDisplayText()); + response.setPublic(result.isPublicTemplate()); + response.setCreated(result.getCreated()); + response.setFormat(result.getFormat()); + response.setOsTypeId(result.getGuestOSUuid()); + response.setOsTypeName(result.getGuestOSName()); + response.setBootable(result.isBootable()); + response.setHypervisor(result.getHypervisorType().toString()); + + // populate owner. + ApiResponseHelper.populateOwner(response, result); + + // populate domain + response.setDomainId(result.getDomainUuid()); + response.setDomainName(result.getDomainName()); + + // set details map + if (result.getDetailName() != null) { + Map details = new HashMap(); + details.put(result.getDetailName(), result.getDetailValue()); + response.setDetails(details); + } + + // update tag information + long tag_id = result.getTagId(); + if (tag_id > 0) { + ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); + if (vtag != null) { + response.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); + } + } + + response.setObjectName("iso"); + return response; + } + + + + + @Override + public TemplateResponse setTemplateResponse(TemplateResponse templateResponse, TemplateJoinVO template) { + + // update template zone information + if (template.getDataCenterId() > 0 ){ + TemplateZoneResponse tmplZoneResp = new TemplateZoneResponse(template.getDataCenterUuid(), template.getDataCenterName()); + templateResponse.addZone(tmplZoneResp); + if (templateResponse.getZoneId() == null) { + // set the first found associated zone directly in + // TemplateResponse + templateResponse.setZoneId(template.getDataCenterUuid()); + templateResponse.setZoneName(template.getDataCenterName()); + } + } + + // update details map + if (template.getDetailName() != null){ + Map details = templateResponse.getDetails(); + if ( details == null ){ + details = new HashMap(); + } + details.put(template.getDetailName(), template.getDetailValue()); + templateResponse.setDetails(details); + } + + // update tag information + long tag_id = template.getTagId(); + if (tag_id > 0) { + ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); + if ( vtag != null ){ + templateResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); + } + } + + return templateResponse; + } + + + @Override + public TemplateResponse newIsoResponse(TemplateJoinVO iso) { + + TemplateResponse isoResponse = new TemplateResponse(); + isoResponse.setId(iso.getUuid()); + isoResponse.setName(iso.getName()); + isoResponse.setDisplayText(iso.getDisplayText()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); + isoResponse.setCreated(iso.getCreatedOnStore()); + isoResponse.setReady(iso.getDownloadState() == Status.DOWNLOADED); + isoResponse.setBootable(iso.isBootable()); + isoResponse.setFeatured(iso.isFeatured()); + isoResponse.setCrossZones(iso.isCrossZones()); + isoResponse.setPublic(iso.isPublicTemplate()); + isoResponse.setChecksum(iso.getChecksum()); + + isoResponse.setOsTypeId(iso.getGuestOSUuid()); + isoResponse.setOsTypeName(iso.getGuestOSName()); + + // populate owner. + ApiResponseHelper.populateOwner(isoResponse, iso); + + // populate domain + isoResponse.setDomainId(iso.getDomainUuid()); + isoResponse.setDomainName(iso.getDomainName()); + + // set template zone information + if (iso.getDataCenterId() > 0 ){ + TemplateZoneResponse tmplZoneResp = new TemplateZoneResponse(iso.getDataCenterUuid(), iso.getDataCenterName()); + isoResponse.addZone(tmplZoneResp); + // set the first found associated zone directly in TemplateResponse + isoResponse.setZoneId(iso.getDataCenterUuid()); + isoResponse.setZoneName(iso.getDataCenterName()); + } + + + Account caller = UserContext.current().getCaller(); + boolean isAdmin = false; + if ((caller == null) || BaseCmd.isAdmin(caller.getType())) { + isAdmin = true; + } + + + // If the user is an admin, add the template download status + if (isAdmin || caller.getId() == iso.getAccountId()) { + // add download status + if (iso.getDownloadState() != Status.DOWNLOADED) { + String isoStatus = "Processing"; + if (iso.getDownloadState() == VMTemplateHostVO.Status.DOWNLOADED) { + isoStatus = "Download Complete"; + } else if (iso.getDownloadState() == VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS) { + if (iso.getDownloadPercent() == 100) { + isoStatus = "Installing ISO"; + } else { + isoStatus = iso.getDownloadPercent() + "% Downloaded"; + } + } else { + isoStatus = iso.getErrorString(); + } + isoResponse.setStatus(isoStatus); + } else { + isoResponse.setStatus("Successfully Installed"); + } + } + + Long isoSize = iso.getSize(); + if (isoSize > 0) { + isoResponse.setSize(isoSize); + } + + // update tag information + long tag_id = iso.getTagId(); + if (tag_id > 0) { + ResourceTagJoinVO vtag = ApiDBUtils.findResourceTagViewById(tag_id); + if ( vtag != null ){ + isoResponse.addTag(ApiDBUtils.newResourceTagResponse(vtag, false)); + } + } + + isoResponse.setObjectName("iso"); + return isoResponse; + + } + + @Override + public List newTemplateView(VirtualMachineTemplate template) { + SearchCriteria sc = tmpltIdSearch.create(); + sc.setParameters("id", template.getId()); + return searchIncludingRemoved(sc, null, null, false); + } + + @Override + public List newTemplateView(VirtualMachineTemplate template, long zoneId, boolean readyOnly) { + SearchCriteria sc = tmpltZoneSearch.create(); + sc.setParameters("id", template.getId()); + sc.setParameters("dataCenterId", zoneId); + if ( readyOnly ){ + sc.setParameters("downloadState", VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + } + return searchIncludingRemoved(sc, null, null, false); + } + + + + @Override + public List searchByIds(Long... tmplIds) { + // set detail batch query size + int DETAILS_BATCH_SIZE = 2000; + String batchCfg = _configDao.getValue("detail.batch.query.size"); + if ( batchCfg != null ){ + DETAILS_BATCH_SIZE = Integer.parseInt(batchCfg); + } + // query details by batches + List uvList = new ArrayList(); + // query details by batches + int curr_index = 0; + if ( tmplIds.length > DETAILS_BATCH_SIZE ){ + while ( (curr_index + DETAILS_BATCH_SIZE ) <= tmplIds.length ) { + Long[] ids = new Long[DETAILS_BATCH_SIZE]; + for (int k = 0, j = curr_index; j < curr_index + DETAILS_BATCH_SIZE; j++, k++) { + ids[k] = tmplIds[j]; + } + SearchCriteria sc = tmpltSearch.create(); + sc.setParameters("idIN", ids); + List vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + curr_index += DETAILS_BATCH_SIZE; + } + } + if (curr_index < tmplIds.length) { + int batch_size = (tmplIds.length - curr_index); + // set the ids value + Long[] ids = new Long[batch_size]; + for (int k = 0, j = curr_index; j < curr_index + batch_size; j++, k++) { + ids[k] = tmplIds[j]; + } + SearchCriteria sc = tmpltSearch.create(); + sc.setParameters("idIN", ids); + List vms = searchIncludingRemoved(sc, null, null, false); + if (vms != null) { + uvList.addAll(vms); + } + } + return uvList; + } + + + +} diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java new file mode 100644 index 00000000000..0a6b0f9977c --- /dev/null +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -0,0 +1,1006 @@ +// 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.api.query.vo; + +import java.util.Date; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; + +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.storage.Storage; +import com.cloud.storage.Volume; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.utils.db.GenericDao; +import com.cloud.vm.VirtualMachine; + +@Entity +@Table(name="template_view") +public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { + + @Id + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; + + @Column(name="unique_name") + private String uniqueName; + + @Column(name="name") + private String name; + + @Column(name="format") + private Storage.ImageFormat format; + + @Column(name="public") + private boolean publicTemplate = true; + + @Column(name="featured") + private boolean featured; + + @Column(name="type") + private Storage.TemplateType templateType; + + @Column(name="url") + private String url = null; + + @Column(name="hvm") + private boolean requiresHvm; + + @Column(name="bits") + private int bits; + + @Temporal(value=TemporalType.TIMESTAMP) + @Column(name=GenericDao.CREATED_COLUMN) + private Date created = null; + + @Temporal(value=TemporalType.TIMESTAMP) + @Column(name="created_on_store") + private Date createdOnStore = null; + + @Column(name=GenericDao.REMOVED) + @Temporal(TemporalType.TIMESTAMP) + private Date removed; + + @Column(name="checksum") + private String checksum; + + @Column(name="display_text", length=4096) + private String displayText; + + @Column(name="enable_password") + private boolean enablePassword; + + @Column(name="guest_os_id") + private long guestOSId; + + @Column(name="guest_os_uuid") + private String guestOSUuid; + + @Column(name="guest_os_name") + private String guestOSName; + + @Column(name="bootable") + private boolean bootable = true; + + @Column(name="prepopulate") + private boolean prepopulate = false; + + @Column(name="cross_zones") + private boolean crossZones = false; + + @Column(name="hypervisor_type") + @Enumerated(value=EnumType.STRING) + private HypervisorType hypervisorType; + + @Column(name="extractable") + private boolean extractable = true; + + @Column(name="source_template_id") + private Long sourceTemplateId; + + @Column(name="source_template_uuid") + private String sourceTemplateUuid; + + + @Column(name="template_tag") + private String templateTag; + + @Column(name="sort_key") + private int sortKey; + + @Column(name="enable_sshkey") + private boolean enableSshKey; + + @Column(name="account_id") + private long accountId; + + @Column(name="account_uuid") + private String accountUuid; + + @Column(name="account_name") + private String accountName = null; + + @Column(name="account_type") + private short accountType; + + @Column(name="domain_id") + private long domainId; + + @Column(name="domain_uuid") + private String domainUuid; + + @Column(name="domain_name") + private String domainName = null; + + @Column(name="domain_path") + private String domainPath = null; + + @Column(name="project_id") + private long projectId; + + @Column(name="project_uuid") + private String projectUuid; + + @Column(name="project_name") + private String projectName; + + @Column(name="data_center_id") + private long dataCenterId; + + @Column(name="data_center_uuid") + private String dataCenterUuid; + + @Column(name="data_center_name") + private String dataCenterName; + + @Column (name="download_state") + @Enumerated(EnumType.STRING) + private Status downloadState; + + @Column (name="download_pct") + private int downloadPercent; + + @Column (name="error_str") + private String errorString; + + @Column (name="size") + private long size; + + @Column(name="destroyed") + boolean destroyed = false; + + @Column(name="lp_account_id") + private Long sharedAccountId; + + @Column(name="detail_name") + private String detailName; + + @Column(name="detail_value") + private String detailValue; + + + @Column(name="tag_id") + private long tagId; + + @Column(name="tag_uuid") + private String tagUuid; + + @Column(name="tag_key") + private String tagKey; + + @Column(name="tag_value") + private String tagValue; + + @Column(name="tag_domain_id") + private long tagDomainId; + + @Column(name="tag_account_id") + private long tagAccountId; + + @Column(name="tag_resource_id") + private long tagResourceId; + + @Column(name="tag_resource_uuid") + private String tagResourceUuid; + + @Column(name="tag_resource_type") + @Enumerated(value=EnumType.STRING) + private TaggedResourceType tagResourceType; + + @Column(name="tag_customer") + private String tagCustomer; + + + + public TemplateJoinVO() { + } + + + + @Override + public long getId() { + return id; + } + + + + @Override + public void setId(long id) { + this.id = id; + } + + + + @Override + public String getUuid() { + return uuid; + } + + + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + + + public String getName() { + return name; + } + + + + public void setName(String name) { + this.name = name; + } + + + public Date getCreated() { + return created; + } + + + + public void setCreated(Date created) { + this.created = created; + } + + + + public Date getRemoved() { + return removed; + } + + + + public void setRemoved(Date removed) { + this.removed = removed; + } + + + + @Override + public long getAccountId() { + return accountId; + } + + + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + + + @Override + public String getAccountUuid() { + return accountUuid; + } + + + + public void setAccountUuid(String accountUuid) { + this.accountUuid = accountUuid; + } + + + + @Override + public String getAccountName() { + return accountName; + } + + + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + + + @Override + public short getAccountType() { + return accountType; + } + + + + public void setAccountType(short accountType) { + this.accountType = accountType; + } + + + + @Override + public long getDomainId() { + return domainId; + } + + + + public void setDomainId(long domainId) { + this.domainId = domainId; + } + + + + @Override + public String getDomainUuid() { + return domainUuid; + } + + + + public void setDomainUuid(String domainUuid) { + this.domainUuid = domainUuid; + } + + + + @Override + public String getDomainName() { + return domainName; + } + + + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + + + @Override + public String getDomainPath() { + return domainPath; + } + + + + public void setDomainPath(String domainPath) { + this.domainPath = domainPath; + } + + + + public long getProjectId() { + return projectId; + } + + + + public void setProjectId(long projectId) { + this.projectId = projectId; + } + + + + @Override + public String getProjectUuid() { + return projectUuid; + } + + + + public void setProjectUuid(String projectUuid) { + this.projectUuid = projectUuid; + } + + + + @Override + public String getProjectName() { + return projectName; + } + + + + public void setProjectName(String projectName) { + this.projectName = projectName; + } + + + + + public boolean isExtractable() { + return extractable; + } + + + + public void setExtractable(boolean extractable) { + this.extractable = extractable; + } + + + + public Storage.TemplateType getTemplateType() { + return templateType; + } + + + + public void setTemplateType(Storage.TemplateType templateType) { + this.templateType = templateType; + } + + + + + + + public long getTagId() { + return tagId; + } + + + + public void setTagId(long tagId) { + this.tagId = tagId; + } + + + + public String getTagUuid() { + return tagUuid; + } + + + + public void setTagUuid(String tagUuid) { + this.tagUuid = tagUuid; + } + + + + public String getTagKey() { + return tagKey; + } + + + + public void setTagKey(String tagKey) { + this.tagKey = tagKey; + } + + + + public String getTagValue() { + return tagValue; + } + + + + public void setTagValue(String tagValue) { + this.tagValue = tagValue; + } + + + + public long getTagDomainId() { + return tagDomainId; + } + + + + public void setTagDomainId(long tagDomainId) { + this.tagDomainId = tagDomainId; + } + + + + public long getTagAccountId() { + return tagAccountId; + } + + + + public void setTagAccountId(long tagAccountId) { + this.tagAccountId = tagAccountId; + } + + + + public long getTagResourceId() { + return tagResourceId; + } + + + + public void setTagResourceId(long tagResourceId) { + this.tagResourceId = tagResourceId; + } + + + + public String getTagResourceUuid() { + return tagResourceUuid; + } + + + + public void setTagResourceUuid(String tagResourceUuid) { + this.tagResourceUuid = tagResourceUuid; + } + + + + public TaggedResourceType getTagResourceType() { + return tagResourceType; + } + + + + public void setTagResourceType(TaggedResourceType tagResourceType) { + this.tagResourceType = tagResourceType; + } + + + + public String getTagCustomer() { + return tagCustomer; + } + + + + public void setTagCustomer(String tagCustomer) { + this.tagCustomer = tagCustomer; + } + + + + public long getDataCenterId() { + return dataCenterId; + } + + + + public void setDataCenterId(long dataCenterId) { + this.dataCenterId = dataCenterId; + } + + + + public String getDataCenterUuid() { + return dataCenterUuid; + } + + + + public void setDataCenterUuid(String dataCenterUuid) { + this.dataCenterUuid = dataCenterUuid; + } + + + + public String getDataCenterName() { + return dataCenterName; + } + + + + public void setDataCenterName(String dataCenterName) { + this.dataCenterName = dataCenterName; + } + + + + public String getUniqueName() { + return uniqueName; + } + + + + public void setUniqueName(String uniqueName) { + this.uniqueName = uniqueName; + } + + + + public boolean isPublicTemplate() { + return publicTemplate; + } + + + + public void setPublicTemplate(boolean publicTemplate) { + this.publicTemplate = publicTemplate; + } + + + + public boolean isFeatured() { + return featured; + } + + + + public void setFeatured(boolean featured) { + this.featured = featured; + } + + + + public String getUrl() { + return url; + } + + + + public void setUrl(String url) { + this.url = url; + } + + + + public boolean isRequiresHvm() { + return requiresHvm; + } + + + + public void setRequiresHvm(boolean requiresHvm) { + this.requiresHvm = requiresHvm; + } + + + + public int getBits() { + return bits; + } + + + + public void setBits(int bits) { + this.bits = bits; + } + + + + public String getChecksum() { + return checksum; + } + + + + public void setChecksum(String checksum) { + this.checksum = checksum; + } + + + + public String getDisplayText() { + return displayText; + } + + + + public void setDisplayText(String displayText) { + this.displayText = displayText; + } + + + + public boolean isEnablePassword() { + return enablePassword; + } + + + + public void setEnablePassword(boolean enablePassword) { + this.enablePassword = enablePassword; + } + + + + public long getGuestOSId() { + return guestOSId; + } + + + + public void setGuestOSId(long guestOSId) { + this.guestOSId = guestOSId; + } + + + + public String getGuestOSUuid() { + return guestOSUuid; + } + + + + public void setGuestOSUuid(String guestOSUuid) { + this.guestOSUuid = guestOSUuid; + } + + + + public String getGuestOSName() { + return guestOSName; + } + + + + public void setGuestOSName(String guestOSName) { + this.guestOSName = guestOSName; + } + + + + public boolean isBootable() { + return bootable; + } + + + + public void setBootable(boolean bootable) { + this.bootable = bootable; + } + + + + public boolean isPrepopulate() { + return prepopulate; + } + + + + public void setPrepopulate(boolean prepopulate) { + this.prepopulate = prepopulate; + } + + + + public boolean isCrossZones() { + return crossZones; + } + + + + public void setCrossZones(boolean crossZones) { + this.crossZones = crossZones; + } + + + + public HypervisorType getHypervisorType() { + return hypervisorType; + } + + + + public void setHypervisorType(HypervisorType hypervisorType) { + this.hypervisorType = hypervisorType; + } + + + + public Long getSourceTemplateId() { + return sourceTemplateId; + } + + + + public void setSourceTemplateId(Long sourceTemplateId) { + this.sourceTemplateId = sourceTemplateId; + } + + + + public String getSourceTemplateUuid() { + return sourceTemplateUuid; + } + + + + public void setSourceTemplateUuid(String sourceTemplateUuid) { + this.sourceTemplateUuid = sourceTemplateUuid; + } + + + + public String getTemplateTag() { + return templateTag; + } + + + + public void setTemplateTag(String templateTag) { + this.templateTag = templateTag; + } + + + + public int getSortKey() { + return sortKey; + } + + + + public void setSortKey(int sortKey) { + this.sortKey = sortKey; + } + + + + public boolean isEnableSshKey() { + return enableSshKey; + } + + + + public void setEnableSshKey(boolean enableSshKey) { + this.enableSshKey = enableSshKey; + } + + + + public Status getDownloadState() { + return downloadState; + } + + + + public void setDownloadState(Status downloadState) { + this.downloadState = downloadState; + } + + + + public long getSize() { + return size; + } + + + + public void setSize(long size) { + this.size = size; + } + + + + public boolean isDestroyed() { + return destroyed; + } + + + + public void setDestroyed(boolean destroyed) { + this.destroyed = destroyed; + } + + + + public Long getSharedAccountId() { + return sharedAccountId; + } + + + + public void setSharedAccountId(Long sharedAccountId) { + this.sharedAccountId = sharedAccountId; + } + + + + public String getDetailName() { + return detailName; + } + + + + public void setDetailName(String detailName) { + this.detailName = detailName; + } + + + + public String getDetailValue() { + return detailValue; + } + + + + public void setDetailValue(String detailValue) { + this.detailValue = detailValue; + } + + + + public Date getCreatedOnStore() { + return createdOnStore; + } + + + + public void setCreatedOnStore(Date createdOnStore) { + this.createdOnStore = createdOnStore; + } + + + + public Storage.ImageFormat getFormat() { + return format; + } + + + + public void setFormat(Storage.ImageFormat format) { + this.format = format; + } + + + + public int getDownloadPercent() { + return downloadPercent; + } + + + + public void setDownloadPercent(int downloadPercent) { + this.downloadPercent = downloadPercent; + } + + + + public String getErrorString() { + return errorString; + } + + + + public void setErrorString(String errorString) { + this.errorString = errorString; + } + + + +} diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index ff60ce53fed..c2871d9f4d8 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1112,70 +1112,10 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return new Pair, Integer>(result.first(), result.second()); } - @Override - public Set> listIsos(ListIsosCmd cmd) throws IllegalArgumentException, InvalidParameterValueException { - TemplateFilter isoFilter = TemplateFilter.valueOf(cmd.getIsoFilter()); - Account caller = UserContext.current().getCaller(); - Map tags = cmd.getTags(); - boolean listAll = false; - if (isoFilter != null && isoFilter == TemplateFilter.all) { - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { - throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); - } - listAll = true; - } - List permittedAccountIds = new ArrayList(); - Ternary domainIdRecursiveListProject = new Ternary( - cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, cmd.getId(), cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, - domainIdRecursiveListProject, listAll, false); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - - List permittedAccounts = new ArrayList(); - for (Long accountId : permittedAccountIds) { - permittedAccounts.add(_accountMgr.getAccount(accountId)); - } - - HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); - return listTemplates(cmd.getId(), cmd.getIsoName(), cmd.getKeyword(), isoFilter, true, cmd.isBootable(), cmd.getPageSizeVal(), - cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, - listProjectResourcesCriteria, tags); - } - - @Override - public Set> listTemplates(ListTemplatesCmd cmd) throws IllegalArgumentException, InvalidParameterValueException { - TemplateFilter templateFilter = TemplateFilter.valueOf(cmd.getTemplateFilter()); - Long id = cmd.getId(); - Map tags = cmd.getTags(); - Account caller = UserContext.current().getCaller(); - - boolean listAll = false; - if (templateFilter != null && templateFilter == TemplateFilter.all) { - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { - throw new InvalidParameterValueException("Filter " + TemplateFilter.all + " can be specified by admin only"); - } - listAll = true; - } - - List permittedAccountIds = new ArrayList(); - Ternary domainIdRecursiveListProject = new Ternary( - cmd.getDomainId(), cmd.isRecursive(), null); - _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccountIds, domainIdRecursiveListProject, - listAll, false); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - List permittedAccounts = new ArrayList(); - for (Long accountId : permittedAccountIds) { - permittedAccounts.add(_accountMgr.getAccount(accountId)); - } - - boolean showDomr = ((templateFilter != TemplateFilter.selfexecutable) && (templateFilter != TemplateFilter.featured)); - HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor()); - - return listTemplates(id, cmd.getTemplateName(), cmd.getKeyword(), templateFilter, false, null, cmd.getPageSizeVal(), cmd.getStartIndex(), - cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); - } + /* TODO: this method should go away. Keep here just in case that our latest refactoring using template_store_ref missed anything + * in handling Swift or S3. private Set> listTemplates(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { @@ -1274,7 +1214,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return templateZonePairSet; } - +*/ @Override diff --git a/server/src/com/cloud/storage/dao/VMTemplateDao.java b/server/src/com/cloud/storage/dao/VMTemplateDao.java index 726337129a3..8c2b941c7b1 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDao.java @@ -37,11 +37,11 @@ import com.cloud.utils.fsm.StateDao; * Data Access Object for vm_templates table */ public interface VMTemplateDao extends GenericDao, StateDao { - - + + public List listByPublic(); public VMTemplateVO findByName(String templateName); - public VMTemplateVO findByTemplateName(String templateName); + public VMTemplateVO findByTemplateName(String templateName); //public void update(VMTemplateVO template); @@ -53,11 +53,13 @@ public interface VMTemplateDao extends GenericDao, StateDao< public List findIsosByIdAndPath(Long domainId, Long accountId, String path); public List listReadyTemplates(); public List listByAccountId(long accountId); + + /* TODO: these routines should go away, the logic has been consolidated and refactored in QueryService public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags); - + public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, Map tags); @@ -65,10 +67,11 @@ public interface VMTemplateDao extends GenericDao, StateDao< public Set> searchS3Templates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, Map tags); + */ public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); - public List listAllInZone(long dataCenterId); - + public List listAllInZone(long dataCenterId); + public List listByHypervisorType(List hyperTypes); public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags); public List userIsoSearch(boolean listRemoved); @@ -78,7 +81,7 @@ public interface VMTemplateDao extends GenericDao, StateDao< VMTemplateVO findRoutingTemplate(HypervisorType type); List listPrivateTemplatesByHost(Long hostId); public Long countTemplatesForAccount(long accountId); - + List findTemplatesToSyncToS3(); } diff --git a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index d9a26d3ca66..1bc77df3d3c 100755 --- a/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/server/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -16,25 +16,17 @@ // under the License. package com.cloud.storage.dao; -import static com.cloud.utils.StringUtils.join; -import static com.cloud.utils.db.DbUtil.closeResources; - import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; -import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.Set; - import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.log4j.Logger; @@ -42,25 +34,19 @@ import org.springframework.stereotype.Component; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.template.VirtualMachineTemplate.TemplateFilter; -import com.cloud.user.Account; -import com.cloud.utils.Pair; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; @@ -92,6 +78,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem DomainDao _domainDao; @Inject DataCenterDao _dcDao; + + /* TODO: these direct sql should go away with recent QueryService refactoring to handle listTemplatesCmd. Keep here just for + * potential bug reference. private final String SELECT_TEMPLATE_HOST_REF = "SELECT t.id, h.data_center_id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; @@ -103,6 +92,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private final String SELECT_TEMPLATE_S3_REF = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; + */ private static final String SELECT_S3_CANDIDATE_TEMPLATES = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, " + "t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, t.checksum, t.display_text, " + @@ -397,6 +387,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return routerTmpltName; } + /* @Override public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, Map tags) { @@ -538,7 +529,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem Transaction txn = Transaction.currentTxn(); txn.start(); - /* Use LinkedHashSet here to guarantee iteration order */ + // Use LinkedHashSet here to guarantee iteration order Set> templateZonePairList = new LinkedHashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; @@ -751,7 +742,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return templateZonePairList; } + */ + /* private String getExtrasWhere(TemplateFilter templateFilter, String name, String keyword, boolean isIso, Boolean bootable, HypervisorType hyperType, Long zoneId, boolean onlyReady, boolean showDomr) { String sql = ""; if (keyword != null) { @@ -811,6 +804,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } return sql; } + */ @Override @DB @@ -873,7 +867,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } } - public VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType) { + @Override + public VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType) { SearchCriteria sc = tmpltTypeHyperSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); @@ -938,18 +933,14 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return result; } - private boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || - (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); - } + @Override public List findTemplatesToSyncToS3() { return executeList(SELECT_S3_CANDIDATE_TEMPLATES, new Object[] {}); } + /* @Override public Set> searchS3Templates(final String name, final String keyword, final TemplateFilter templateFilter, @@ -1083,6 +1074,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return templateZonePairList; } +*/ @Override public boolean updateState(TemplateState currentState, TemplateEvent event, diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 9e524228fe1..619cd7ece4c 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -2118,6 +2118,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, boolean readyOnly) { + // readyOnly flag is not used at all List hosts = _ssvmMgr .listSecondaryStorageHostsInOneZone(zoneId); if (hosts == null || hosts.size() == 0) { diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index fd030889909..6a7365f9054 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -519,3 +519,98 @@ INSERT INTO `cloud`.`vm_template` (id, unique_name, name, public, created, type, VALUES (10, 'routing-10', 'SystemVM Template (LXC)', 0, now(), 'SYSTEM', 0, 64, 1, 'http://download.cloud.com/templates/acton/acton-systemvm-02062012.qcow2.bz2', '2755de1f9ef2ce4d6f2bee2efbb4da92', 0, 'SystemVM Template (LXC)', 'QCOW2', 15, 0, 1, 'LXC'); -- END: support for LXC + +DROP VIEW IF EXISTS `cloud`.`template_view`; +CREATE VIEW `cloud`.`template_view` AS + select + vm_template.id, + vm_template.uuid, + vm_template.unique_name, + vm_template.name, + vm_template.public, + vm_template.featured, + vm_template.type, + vm_template.hvm, + vm_template.bits, + vm_template.url, + vm_template.format, + vm_template.created, + vm_template.checksum, + vm_template.display_text, + vm_template.enable_password, + vm_template.guest_os_id, + guest_os.uuid guest_os_uuid, + guest_os.display_name guest_os_name, + vm_template.bootable, + vm_template.prepopulate, + vm_template.cross_zones, + vm_template.hypervisor_type, + vm_template.extractable, + vm_template.template_tag, + vm_template.sort_key, + source_template.id source_template_id, + source_template.uuid source_template_uuid, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + launch_permission.account_id lp_account_id, + template_store_ref.download_state, + template_store_ref.download_pct, + template_store_ref.error_str, + template_store_ref.size, + template_store_ref.destroyed, + template_store_ref.created created_on_store, + vm_template_details.name detail_name, + vm_template_details.value detail_value, + resource_tags.id tag_id, + resource_tags.uuid tag_uuid, + resource_tags.key tag_key, + resource_tags.value tag_value, + resource_tags.domain_id tag_domain_id, + resource_tags.account_id tag_account_id, + resource_tags.resource_id tag_resource_id, + resource_tags.resource_uuid tag_resource_uuid, + resource_tags.resource_type tag_resource_type, + resource_tags.customer tag_customer + from + `cloud`.`vm_template` + inner join + `cloud`.`guest_os` ON guest_os.id = vm_template.guest_os_id + inner join + `cloud`.`account` ON account.id = vm_template.account_id + inner join + `cloud`.`domain` ON domain.id = account.domain_id + left join + `cloud`.`projects` ON projects.project_account_id = account.id + left join + `cloud`.`vm_template_details` ON vm_template_details.template_id = vm_template.id + left join + `cloud`.`vm_template` source_template ON source_template.id = vm_template.source_template_id + left join + `cloud`.`template_zone_ref` ON template_zone_ref.template_id = vm_template.id + AND template_zone_ref.removed is null + left join + `cloud`.`data_center` ON template_zone_ref.zone_id = data_center.id + left join + `cloud`.`image_store` ON image_store.data_center_id = data_center.id OR image_store.scope = 'REGION' + left join + `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id AND template_store_ref.store_id = image_store.id + left join + `cloud`.`launch_permission` ON launch_permission.template_id = vm_template.id + left join + `cloud`.`resource_tags` ON resource_tags.resource_id = vm_template.id + and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO'); + + + From 09ba55103e58cad6479bf3f73b150800f1052538 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 19 Apr 2013 17:09:31 -0700 Subject: [PATCH 037/303] Fix vmware plugin compilation error due to eclipse refactoring. --- .../hypervisor/vmware/VmwareServerDiscoverer.java | 14 +++++++------- .../vmware/manager/VmwareManagerImpl.java | 8 ++++---- .../hypervisor/vmware/resource/VmwareResource.java | 8 ++++---- .../VmwareSecondaryStorageResourceHandler.java | 4 ++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index c4b53c258d6..00647d92b67 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -119,9 +119,9 @@ public class VmwareServerDiscoverer extends DiscovererBase implements public VmwareServerDiscoverer() { s_logger.info("VmwareServerDiscoverer is constructed"); } - + @Override - public Map> find(long dcId, Long podId, Long clusterId, URI url, + public Map> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List hostTags) throws DiscoveryException { if(s_logger.isInfoEnabled()) @@ -312,7 +312,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements .decode(uriFromCluster.getPath())); if (morCluster == null - || !morCluster.getProtocol().equalsIgnoreCase( + || !morCluster.getType().equalsIgnoreCase( "ClusterComputeResource")) { s_logger.warn("Cluster url does not point to a valid vSphere cluster, url: " + clusterDetails.get("url")); @@ -345,7 +345,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements details.put("url", hostMo.getHostName()); details.put("username", username); details.put("password", password); - String guid = morHost.getProtocol() + ":" + morHost.getValue() + String guid = morHost.getType() + ":" + morHost.getValue() + "@" + url.getHost(); details.put("guid", guid); @@ -402,7 +402,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements for (ManagedObjectReference morHost : morHosts) { ManagedObjectReference morParent = (ManagedObjectReference) context .getVimClient().getDynamicProperty(morHost, "parent"); - if (morParent.getProtocol().equalsIgnoreCase( + if (morParent.getType().equalsIgnoreCase( "ClusterComputeResource")) return false; } @@ -410,7 +410,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements for (ManagedObjectReference morHost : morHosts) { ManagedObjectReference morParent = (ManagedObjectReference) context .getVimClient().getDynamicProperty(morHost, "parent"); - if (!morParent.getProtocol().equalsIgnoreCase( + if (!morParent.getType().equalsIgnoreCase( "ClusterComputeResource")) return false; @@ -637,7 +637,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements return VirtualSwitchType.NexusDistributedVirtualSwitch; else if(useDVS) return VirtualSwitchType.VMwareDistributedVirtualSwitch; - else + else return VirtualSwitchType.StandardVirtualSwitch; } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index adcf23b6837..b2e37685d17 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -336,7 +336,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw if(mor != null) { List returnedHostList = new ArrayList(); - if(mor.getProtocol().equals("ComputeResource")) { + if(mor.getType().equals("ComputeResource")) { List hosts = (List)serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert(hosts != null && hosts.size() > 0); @@ -346,7 +346,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(hosts.get(0)); return returnedHostList; - } else if(mor.getProtocol().equals("ClusterComputeResource")) { + } else if(mor.getType().equals("ClusterComputeResource")) { List hosts = (List)serviceContext.getVimClient().getDynamicProperty(mor, "host"); assert(hosts != null); @@ -368,14 +368,14 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw returnedHostList.add(morHost); } return returnedHostList; - } else if(mor.getProtocol().equals("HostSystem")) { + } else if(mor.getType().equals("HostSystem")) { // For ESX host, we need to enable host firewall to allow VNC access HostMO hostMo = new HostMO(serviceContext, mor); prepareHost(hostMo, privateTrafficLabel); returnedHostList.add(mor); return returnedHostList; } else { - s_logger.error("Unsupport host type " + mor.getProtocol() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); + s_logger.error("Unsupport host type " + mor.getType() + ":" + mor.getValue() + " from inventory path: " + hostInventoryPath); return null; } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index b7218ef9f57..0f85f4e71ca 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1755,11 +1755,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa args += " -6 " + cmd.getVmIp6Address(); args += " -u " + cmd.getDuid(); } - + if (!cmd.isDefault()) { args += " -N"; } - + if (s_logger.isDebugEnabled()) { s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /root/edithosts.sh " + args); } @@ -4470,7 +4470,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa ManagedObjectReference morParent = vmOwnerHost.getParentMor(); HashMap portInfo; - if(morParent.getProtocol().equalsIgnoreCase("ClusterComputeResource")) { + if(morParent.getType().equalsIgnoreCase("ClusterComputeResource")) { ClusterMO clusterMo = new ClusterMO(vmOwnerHost.getContext(), morParent); portInfo = clusterMo.getVmVncPortsOnCluster(); } else { @@ -5067,7 +5067,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa @Override public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { - if (_morHyperHost.getProtocol().equalsIgnoreCase("HostSystem")) { + if (_morHyperHost.getType().equalsIgnoreCase("HostSystem")) { return new HostMO(context, _morHyperHost); } return new ClusterMO(context, _morHyperHost); diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java index bb5abb94840..566e750c3fe 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java @@ -221,7 +221,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe morHyperHost.setType(hostTokens[0]); morHyperHost.setValue(hostTokens[1]); - if(morHyperHost.getProtocol().equalsIgnoreCase("HostSystem")) { + if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { HostMO hostMo = new HostMO(context, morHyperHost); try { @@ -278,7 +278,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe morHyperHost.setType(hostTokens[0]); morHyperHost.setValue(hostTokens[1]); - if(morHyperHost.getProtocol().equalsIgnoreCase("HostSystem")) { + if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { HostMO hostMo = new HostMO(context, morHyperHost); try { VmwareHypervisorHostNetworkSummary netSummary = hostMo.getHyperHostNetworkSummary( From b8229349f5e0ba3a81d2456380a05f04d8247708 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 19 Apr 2013 17:46:33 -0700 Subject: [PATCH 038/303] Rename HypervisorHostEndPoint to RemoteHostEndPoint to accommodate ssvm as well. --- .../MockHostEndpointRpcServerDirectCallResource.java | 6 +++--- .../test/MockHypervsiorHostEndPointRpcServer.java | 6 +++--- .../cloudstack/storage/test/volumeServiceTest.java | 4 ++-- .../cloudstack/storage/HostEndpointRpcServer.java | 4 ++-- .../storage/HypervsiorHostEndPointRpcServer.java | 4 ++-- ...rvisorHostEndPoint.java => RemoteHostEndPoint.java} | 10 +++++----- .../storage/endpoint/DefaultEndPointSelector.java | 8 ++++---- 7 files changed, 21 insertions(+), 21 deletions(-) rename engine/storage/src/org/apache/cloudstack/storage/{HypervisorHostEndPoint.java => RemoteHostEndPoint.java} (84%) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java index 4ec2436b06d..2e57ea9cb4a 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java @@ -26,7 +26,7 @@ import javax.inject.Inject; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.HostEndpointRpcServer; -import org.apache.cloudstack.storage.HypervisorHostEndPoint; +import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -46,7 +46,7 @@ public class MockHostEndpointRpcServerDirectCallResource implements HostEndpoint executor = Executors.newScheduledThreadPool(10); } - public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { + public void sendCommandAsync(RemoteHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { // new MockRpcCallBack(host.getHostId(), command, callback); MockRpcCallBack run = ComponentContext.inject(MockRpcCallBack.class); run.setCallback(callback); @@ -56,7 +56,7 @@ public class MockHostEndpointRpcServerDirectCallResource implements HostEndpoint } @Override - public Answer sendCommand(HypervisorHostEndPoint host, Command command) { + public Answer sendCommand(RemoteHostEndPoint host, Command command) { Answer answer; try { answer = agentMgr.send(host.getId(), command); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java index d6985768d91..d55926cf315 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervsiorHostEndPointRpcServer.java @@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.HostEndpointRpcServer; -import org.apache.cloudstack.storage.HypervisorHostEndPoint; +import org.apache.cloudstack.storage.RemoteHostEndPoint; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -60,12 +60,12 @@ public class MockHypervsiorHostEndPointRpcServer implements HostEndpointRpcServe } - public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { + public void sendCommandAsync(RemoteHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { executor.schedule(new MockRpcCallBack(command, callback), 10, TimeUnit.SECONDS); } @Override - public Answer sendCommand(HypervisorHostEndPoint host, Command command) { + public Answer sendCommand(RemoteHostEndPoint host, Command command) { // TODO Auto-generated method stub return null; } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index f8aacc0d0ef..86234c18ff0 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -47,7 +47,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; -import org.apache.cloudstack.storage.HypervisorHostEndPoint; +import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.volume.db.VolumeDao2; @@ -200,7 +200,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { Mockito.when(hostDao.findById(Mockito.anyLong())).thenReturn(host); Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); List eps = new ArrayList(); - eps.add(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), + eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress())); Mockito.when(selector.selectAll(Mockito.any(DataStore.class))).thenReturn(eps); Mockito.when(selector.select(Mockito.any(DataObject.class))).thenReturn(eps.get(0)); diff --git a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java index a316223b24d..01611be3c42 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java +++ b/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java @@ -24,6 +24,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; public interface HostEndpointRpcServer { - void sendCommandAsync(HypervisorHostEndPoint ep, final Command command, final AsyncCompletionCallback callback); - Answer sendCommand(HypervisorHostEndPoint ep, final Command command); + void sendCommandAsync(RemoteHostEndPoint ep, final Command command, final AsyncCompletionCallback callback); + Answer sendCommand(RemoteHostEndPoint ep, final Command command); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java index f441f39ddfa..b6e5788098b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java +++ b/engine/storage/src/org/apache/cloudstack/storage/HypervsiorHostEndPointRpcServer.java @@ -56,7 +56,7 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer { } @Override - public void sendCommandAsync(HypervisorHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { + public void sendCommandAsync(RemoteHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { rpcProvider.newCall(host.getHostAddr()).addCallbackListener(new RpcCallbackListener() { @Override public void onSuccess(Answer result) { @@ -89,7 +89,7 @@ public class HypervsiorHostEndPointRpcServer implements HostEndpointRpcServer { } @Override - public Answer sendCommand(HypervisorHostEndPoint host, Command command) { + public Answer sendCommand(RemoteHostEndPoint host, Command command) { SendCommandContext context = new SendCommandContext(null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().sendCommandCallback(null, null)) diff --git a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java similarity index 84% rename from engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java rename to engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 6c49b1a0e9e..aec7b520391 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -31,8 +31,8 @@ import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; import com.cloud.utils.component.ComponentContext; -public class HypervisorHostEndPoint implements EndPoint { - private static final Logger s_logger = Logger.getLogger(HypervisorHostEndPoint.class); +public class RemoteHostEndPoint implements EndPoint { + private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class); private long hostId; private String hostAddress; @Inject @@ -40,7 +40,7 @@ public class HypervisorHostEndPoint implements EndPoint { @Inject HostEndpointRpcServer rpcServer; - protected HypervisorHostEndPoint() { + protected RemoteHostEndPoint() { } @@ -49,8 +49,8 @@ public class HypervisorHostEndPoint implements EndPoint { this.hostAddress = hostAddress; } - public static HypervisorHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress) { - HypervisorHostEndPoint ep = ComponentContext.inject(HypervisorHostEndPoint.class); + public static RemoteHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress) { + RemoteHostEndPoint ep = ComponentContext.inject(RemoteHostEndPoint.class); ep.configure(hostId, hostAddress); return ep; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index d641f21020a..bda2995952b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -32,7 +32,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; -import org.apache.cloudstack.storage.HypervisorHostEndPoint; +import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -130,7 +130,7 @@ public class DefaultEndPointSelector implements EndPointSelector { return null; } - return HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), + return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress()); } @@ -195,7 +195,7 @@ public class DefaultEndPointSelector implements EndPointSelector { List endPoints = new ArrayList(); if (store.getScope().getScopeType() == ScopeType.HOST) { HostVO host = hostDao.findById(store.getScope().getScopeId()); - endPoints.add(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), + endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress())); } else if (store.getScope().getScopeType() == ScopeType.CLUSTER) { SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); @@ -203,7 +203,7 @@ public class DefaultEndPointSelector implements EndPointSelector { sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); List hosts = sc.find(); for (HostVO host : hosts) { - endPoints.add(HypervisorHostEndPoint.getHypervisorHostEndPoint(host.getId(), + endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress())); } From 6f70fe28e829dcbae0d16cbce7144c6440255391 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 19 Apr 2013 19:37:06 -0700 Subject: [PATCH 039/303] Trigger system vm template download while adding image store. Just a code skeleton, waiting for some code in EndPoint. --- .../DownloadSystemTemplateCommand.java | 154 ++++++++++++++++++ .../LocalNfsSecondaryStorageResource.java | 73 +++++++++ .../resource/NfsSecondaryStorageResource.java | 24 +-- .../api/storage/TemplateService.java | 1 + .../storage/image/TemplateServiceImpl.java | 24 +++ .../com/cloud/storage/StorageManagerImpl.java | 6 + .../storage/download/DownloadMonitor.java | 5 +- .../storage/download/DownloadMonitorImpl.java | 71 ++++++++ 8 files changed, 345 insertions(+), 13 deletions(-) create mode 100644 api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java diff --git a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java new file mode 100644 index 00000000000..d7efcc056e1 --- /dev/null +++ b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java @@ -0,0 +1,154 @@ +// 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.agent.api.storage; + +import java.net.URI; + +import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.DownloadCommand.Proxy; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.template.VirtualMachineTemplate; + + +public class DownloadSystemTemplateCommand extends Command { + public static class PasswordAuth { + String userName; + String password; + public PasswordAuth() { + + } + public PasswordAuth(String user, String password) { + this.userName = user; + this.password = password; + } + public String getUserName() { + return userName; + } + public String getPassword() { + return password; + } + } + + + private PasswordAuth auth; + private Proxy _proxy; + private DataStoreTO _store; + private Long resourceId; + private Long accountId; + private String url; + private Long maxDownloadSizeInBytes; + + protected DownloadSystemTemplateCommand() { + } + + + + public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { + this._store = store; + this.accountId = template.getAccountId(); + this.url = secUrl; + this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + this.resourceId = template.getId(); + } + + + public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { + this._store = store; + this.accountId = template.getAccountId(); + this.url = secUrl; + this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + this.resourceId = template.getId(); + auth = new PasswordAuth(user, passwd); + } + + + + + public PasswordAuth getAuth() { + return auth; + } + + public void setCreds(String userName, String passwd) { + auth = new PasswordAuth(userName, passwd); + } + + public Proxy getProxy() { + return _proxy; + } + + public void setProxy(Proxy proxy) { + _proxy = proxy; + } + + public Long getMaxDownloadSizeInBytes() { + return maxDownloadSizeInBytes; + } + + + public DataStoreTO getDataStore() { + return _store; + } + + + public void setDataStore(DataStoreTO _store) { + this._store = _store; + } + + + public Long getResourceId() { + return resourceId; + } + + + public void setResourceId(Long resourceId) { + this.resourceId = resourceId; + } + + + + public Long getAccountId() { + return accountId; + } + + + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + + + public String getUrl() { + return url; + } + + + + public void setUrl(String url) { + this.url = url; + } + + + + @Override + public boolean executeInSequence() { + // TODO Auto-generated method stub + return false; + } + + +} diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index f0c43102d38..c2583324295 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -1,9 +1,82 @@ package com.cloud.storage.resource; +import static com.cloud.utils.StringUtils.join; +import static java.lang.String.format; +import static java.util.Arrays.asList; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + import org.springframework.stereotype.Component; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; +import com.cloud.agent.api.to.S3TO; +import com.cloud.agent.api.to.SwiftTO; +import com.cloud.utils.S3Utils; +import com.cloud.utils.UriUtils; +import com.cloud.utils.exception.CloudRuntimeException; + @Component public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { + @Override + public Answer executeRequest(Command cmd) { + if (cmd instanceof DownloadSystemTemplateCommand){ + return execute((DownloadSystemTemplateCommand)cmd); + } else { + return Answer.createUnsupportedCommandAnswer(cmd); + } + } + + private Answer execute(DownloadSystemTemplateCommand cmd){ + DataStoreTO dstore = cmd.getDataStore(); + if ( dstore instanceof S3TO ){ + //TODO: how to handle download progress for S3 + S3TO s3 = (S3TO)cmd.getDataStore(); + String url = cmd.getUrl(); + String user = null; + String password = null; + if (cmd.getAuth() != null) { + user = cmd.getAuth().getUserName(); + password = new String(cmd.getAuth().getPassword()); + } + // get input stream from the given url + InputStream in = UriUtils.getInputStreamFromUrl(url, user, password); + URI uri; + URL urlObj; + try { + uri = new URI(url); + urlObj = new URL(url); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("URI is incorrect: " + url); + } catch (MalformedURLException e) { + throw new CloudRuntimeException("URL is incorrect: " + url); + } + + final String bucket = s3.getBucketName(); + String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR); + S3Utils.putObject(s3, in, bucket, key); + return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url, + cmd.getResourceId(), bucket)); + } + else if ( dstore instanceof NfsTO ){ + return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates"); + } + else if ( dstore instanceof SwiftTO ){ + //TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle + // source is url, most likely we need to modify our existing swiftUpload python script. + return new Answer(cmd, false, "Swift is not currently support DownloadCommand"); + } + else{ + return new Answer(cmd, false, "Unsupported image data store: " + dstore); + } + } } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 3ad07589973..e8abcbf1a67 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -221,7 +221,7 @@ SecondaryStorageResource { return Answer.createUnsupportedCommandAnswer(cmd); } } - + protected Answer downloadFromS3ToNfs(CopyCmd cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); @@ -264,27 +264,27 @@ SecondaryStorageResource { return new Answer(cmd, false, errMsg); } } - + protected Answer downloadFromSwiftToNfs(CopyCmd cmd, DataTO srcData, SwiftTO srcImageStore, DataTO destData, NfsTO destImageStore) { return Answer.createUnsupportedCommandAnswer(cmd); - } - + } + protected Answer execute(CopyCmd cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore(); - - if (srcDataStore.getRole() == DataStoreRole.Image + + if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache ) { - + if (!(destDataStore instanceof NfsTO)) { s_logger.debug("only support nfs as cache storage"); - return Answer.createUnsupportedCommandAnswer(cmd); + return Answer.createUnsupportedCommandAnswer(cmd); } - + if (srcDataStore instanceof S3TO) { return downloadFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, destData, (NfsTO)destDataStore); @@ -292,15 +292,15 @@ SecondaryStorageResource { return downloadFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, (NfsTO)destDataStore); } else { - return Answer.createUnsupportedCommandAnswer(cmd); + return Answer.createUnsupportedCommandAnswer(cmd); } - + } return Answer.createUnsupportedCommandAnswer(cmd); } @SuppressWarnings("unchecked") - private String determineS3TemplateDirectory(final Long accountId, + protected String determineS3TemplateDirectory(final Long accountId, final Long templateId) { return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId), S3Utils.SEPARATOR); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index 6bb58e0d4d6..ec027fe9e84 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -32,4 +32,5 @@ public interface TemplateService { void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId); void handleTemplateSync(DataStore store); + void downloadBootstrapSysTemplate(DataStore store); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index c16e47c7ee4..0a249607e46 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -185,6 +185,30 @@ public class TemplateServiceImpl implements TemplateService { return future; } + @Override + public void downloadBootstrapSysTemplate(DataStore store) { + Set toBeDownloaded = new HashSet(); + + List rtngTmplts = _templateDao.listAllSystemVMTemplates(); + List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); + + for (VMTemplateVO rtngTmplt : rtngTmplts) { + toBeDownloaded.add(rtngTmplt); + } + + for (VMTemplateVO builtinTmplt : defaultBuiltin) { + toBeDownloaded.add(builtinTmplt); + } + + for (VMTemplateVO template : toBeDownloaded) { + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); + if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { + _dlMonitor.downloadBootstrapSysTemplateToStorage(template, store, null); + } + } + } + + @Override public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index fb3d3207ad3..22365752a23 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -60,6 +60,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; @@ -325,6 +326,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStoreManager _dataStoreMgr; @Inject DataStoreProviderManager _dataStoreProviderMgr; + @Inject + private TemplateService _imageSrv; protected List _storagePoolAllocators; public List getStoragePoolAllocators() { @@ -1986,6 +1989,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new CloudRuntimeException("Failed to add data store", e); } + // trigger system vm template download + this._imageSrv.downloadBootstrapSysTemplate(store); + return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); } diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index e709e90ff70..efbdbe2c5c6 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -33,7 +33,10 @@ import com.cloud.utils.component.Manager; */ public interface DownloadMonitor extends Manager{ - public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + // when ssvm is not available yet + public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + + public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); public void cancelAllDownloads(Long templateId); diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 6af8db5d4c9..c7b360aa77a 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -30,6 +30,9 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -48,6 +51,7 @@ import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.manager.Commands; @@ -177,6 +181,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor protected UserVmDao _userVmDao; @Inject protected AccountManager _accountMgr; + @Inject + EndPointSelector _epSelector; + @Inject + TemplateDataFactory tmplFactory; private Boolean _sslCopy = new Boolean(false); private String _copyAuthPasswd; @@ -423,6 +431,69 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } + + @Override + public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + boolean downloadJobExists = false; + TemplateDataStoreVO vmTemplateStore = null; + + vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); + if (vmTemplateStore == null) { + // This method can be invoked other places, for example, + // handleTemplateSync, in that case, vmTemplateStore may be null + vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, + VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); + _vmTemplateStoreDao.persist(vmTemplateStore); + } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { + downloadJobExists = true; + } + + Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); + String secUrl = store.getUri(); + if (vmTemplateStore != null) { + start(); + DownloadSystemTemplateCommand dcmd = new DownloadSystemTemplateCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); + dcmd.setProxy(getHttpProxy()); + // TODO: handle S3 download progress + // if (downloadJobExists) { + // dcmd = new DownloadProgressCommand(dcmd, + // vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); + // } + if (vmTemplateStore.isCopy()) { + dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); + } + EndPoint endPoint = _epSelector.select(this.tmplFactory.getTemplate(template.getId(), store)); + if (endPoint == null) { + s_logger.warn("There is no endpoint to send download template command"); + return; + } + // TODO: wait for Edison's code to pass a listener to + // LocalHostEndPoint + /* + DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, + _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + if (downloadJobExists) { + // due to handling existing download job issues, we still keep + // downloadState in template_store_ref to avoid big change in + // DownloadListener to use + // new ObjectInDataStore.State transition. TODO: fix this later + // to be able to remove downloadState from template_store_ref. + dl.setCurrState(vmTemplateStore.getDownloadState()); + } + DownloadListener old = null; + synchronized (_listenerTemplateMap) { + old = _listenerTemplateMap.put(vmTemplateStore, dl); + } + if (old != null) { + old.abandon(); + } + */ + // endPoint.sendMessageAsync(dcmd, callback); + endPoint.sendMessage(dcmd); // wait for Edison's callback code + + } + } + @Override public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); From 86913ab4d37bdd22e79c1992501715d9c2d5b9f9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 19 Apr 2013 23:01:59 -0700 Subject: [PATCH 040/303] Use data motion service to implement copy template. --- .../api/storage/TemplateService.java | 24 ++- .../storage/image/TemplateServiceImpl.java | 175 +++++++++++++----- .../storage/test/volumeServiceTest.java | 45 ++--- .../template/HypervisorTemplateAdapter.java | 7 +- .../cloud/template/TemplateManagerImpl.java | 89 ++++----- 5 files changed, 224 insertions(+), 116 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index ec027fe9e84..2fc6d3d1f1e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; @@ -25,10 +26,25 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import com.cloud.hypervisor.Hypervisor.HypervisorType; public interface TemplateService { - AsyncCallFuture createTemplateAsync(TemplateInfo template, DataStore store); - AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); - AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); - AsyncCallFuture deleteTemplateAsync(TemplateInfo template); + + public class TemplateApiResult extends CommandResult { + private final TemplateInfo template; + public TemplateApiResult(TemplateInfo template) { + this.template = template; + } + + public TemplateInfo getTemplate() { + return this.template; + } + } + + + AsyncCallFuture createTemplateAsync(TemplateInfo template, DataStore store); + AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); + AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); + AsyncCallFuture deleteTemplateAsync(TemplateInfo template); + AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, + DataStore destStore); void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId); void handleTemplateSync(DataStore store); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 0a249607e46..ccdcc5ac516 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -28,15 +28,20 @@ import java.util.Set; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; + import com.cloud.storage.template.TemplateProp; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -68,8 +73,11 @@ import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; +import com.cloud.storage.VolumeVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; @@ -93,6 +101,8 @@ public class TemplateServiceImpl implements TemplateService { @Inject DataStoreManager _storeMgr; @Inject + DataMotionService _motionSrv; + @Inject ResourceLimitService _resourceLimitMgr; @Inject AccountManager _accountMgr; @@ -120,33 +130,18 @@ public class TemplateServiceImpl implements TemplateService { UserVmDao _userVmDao; @Inject VolumeDao _volumeDao; + @Inject + TemplateDataFactory _templateFactory; - class CreateTemplateContext extends AsyncRpcConext { - final TemplateInfo srcTemplate; - final DataStore store; - final AsyncCallFuture future; - final DataObject templateOnStore; - public CreateTemplateContext(AsyncCompletionCallback callback, TemplateInfo srcTemplate, - AsyncCallFuture future, - DataStore store, - DataObject templateOnStore - ) { - super(callback); - this.srcTemplate = srcTemplate; - this.future = future; - this.store = store; - this.templateOnStore = templateOnStore; - } - } - class DeleteTemplateContext extends AsyncRpcConext { + class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; - final AsyncCallFuture future; + final AsyncCallFuture future; - public DeleteTemplateContext(AsyncCompletionCallback callback, TemplateObject template, - AsyncCallFuture future) { + public TemplateOpContext(AsyncCompletionCallback callback, TemplateObject template, + AsyncCallFuture future) { super(callback); this.template = template; this.future = future; @@ -156,7 +151,7 @@ public class TemplateServiceImpl implements TemplateService { return template; } - public AsyncCallFuture getFuture() { + public AsyncCallFuture getFuture() { return future; } @@ -164,21 +159,17 @@ public class TemplateServiceImpl implements TemplateService { } @Override - public AsyncCallFuture createTemplateAsync( + public AsyncCallFuture createTemplateAsync( TemplateInfo template, DataStore store) { - TemplateObject to = (TemplateObject) template; - AsyncCallFuture future = new AsyncCallFuture(); + AsyncCallFuture future = new AsyncCallFuture(); // persist template_store_ref entry DataObject templateOnStore = store.create(template); // update template_store_ref state templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); - CreateTemplateContext context = new CreateTemplateContext(null, - template, - future, - store, - templateOnStore - ); + TemplateOpContext context = new TemplateOpContext(null, + (TemplateObject)templateOnStore, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); store.getDriver().createAsync(templateOnStore, caller); @@ -470,15 +461,14 @@ public class TemplateServiceImpl implements TemplateService { protected Void createTemplateCallback(AsyncCallbackDispatcher callback, - CreateTemplateContext context) { - TemplateObject template = (TemplateObject)context.srcTemplate; - AsyncCallFuture future = context.future; - CommandResult result = new CommandResult(); - DataObject templateOnStore = context.templateOnStore; + TemplateOpContext context) { + TemplateObject template = (TemplateObject)context.getTemplate(); + AsyncCallFuture future = context.getFuture(); + TemplateApiResult result = new TemplateApiResult(template); CreateCmdResult callbackResult = callback.getResult(); if (callbackResult.isFailed()) { try { - templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); + template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); template.stateTransit(TemplateEvent.OperationFailed); } catch (NoTransitionException e) { s_logger.debug("Failed to update template state", e); @@ -489,7 +479,7 @@ public class TemplateServiceImpl implements TemplateService { } try { - templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); + template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); template.stateTransit(TemplateEvent.OperationSucceeded); } catch (NoTransitionException e) { s_logger.debug("Failed to transit state", e); @@ -503,22 +493,22 @@ public class TemplateServiceImpl implements TemplateService { } @Override - public AsyncCallFuture deleteTemplateAsync( + public AsyncCallFuture deleteTemplateAsync( TemplateInfo template) { TemplateObject to = (TemplateObject) template; // update template_store_ref status to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); - AsyncCallFuture future = new AsyncCallFuture(); + AsyncCallFuture future = new AsyncCallFuture(); - DeleteTemplateContext context = new DeleteTemplateContext(null, to, future); + TemplateOpContext context = new TemplateOpContext(null, to, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().deleteTemplateCallback(null, null)).setContext(context); to.getDataStore().getDriver().deleteAsync(to, caller); return future; } - public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, DeleteTemplateContext context) { - CommandResult result = callback.getResult(); + public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, TemplateOpContext context) { + TemplateApiResult result = callback.getResult(); TemplateObject vo = context.getTemplate(); // we can only update state in template_store_ref table if (result.isSuccess()) { @@ -531,19 +521,114 @@ public class TemplateServiceImpl implements TemplateService { } @Override - public AsyncCallFuture createTemplateFromSnapshotAsync( + public AsyncCallFuture createTemplateFromSnapshotAsync( SnapshotInfo snapshot, TemplateInfo template, DataStore store) { // TODO Auto-generated method stub return null; } @Override - public AsyncCallFuture createTemplateFromVolumeAsync( + public AsyncCallFuture createTemplateFromVolumeAsync( VolumeInfo volume, TemplateInfo template, DataStore store) { // TODO Auto-generated method stub return null; } + @Override + public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, + DataStore destStore) { + AsyncCallFuture future = new AsyncCallFuture(); + TemplateApiResult res = new TemplateApiResult(srcTemplate); + try{ + // create one entry in template_store_ref + TemplateDataStoreVO destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId()); + if (destTmpltStore == null) { + destTmpltStore = new TemplateDataStoreVO(destStore.getId(), srcTemplate.getId()); + destTmpltStore.setCopy(true); + _vmTemplateStoreDao.persist(destTmpltStore); + } + TemplateInfo destTemplate = this._templateFactory.getTemplate(destTmpltStore.getTemplateId(), destStore); + destTemplate.processEvent(Event.CreateOnlyRequested); + srcTemplate.processEvent(Event.CopyingRequested); + CopyTemplateContext context = new CopyTemplateContext(null, future, srcTemplate, + destTemplate, + destStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null)) + .setContext(context); + this._motionSrv.copyAsync(srcTemplate, destTemplate, caller); + } catch (Exception e) { + s_logger.debug("Failed to copy volume", e); + res.setResult(e.toString()); + future.complete(res); + } + return future; + } + protected Void copyTemplateCallBack(AsyncCallbackDispatcher callback, + CopyTemplateContext context) { + TemplateInfo srcTemplate = context.getSrcTemplate(); + TemplateInfo destTemplate = context.getDestTemplate(); + CopyCommandResult result = callback.getResult(); + AsyncCallFuture future = context.getFuture(); + TemplateApiResult res = new TemplateApiResult(destTemplate); + try { + if (result.isFailed()) { + res.setResult(result.getResult()); + destTemplate.processEvent(Event.OperationFailed); + srcTemplate.processEvent(Event.OperationFailed); + // remove entry from template_store_ref + TemplateDataStoreVO destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(context.getDestStore().getId(), destTemplate.getId()); + _vmTemplateStoreDao.remove(destTmpltStore.getId()); + future.complete(res); + return null; + } + srcTemplate.processEvent(Event.OperationSuccessed); + destTemplate.processEvent(Event.OperationSuccessed); + future.complete(res); + return null; + } catch (Exception e) { + s_logger.debug("Failed to process copy template callback", e); + res.setResult(e.toString()); + future.complete(res); + } + + return null; + } + + class CopyTemplateContext extends AsyncRpcConext { + final TemplateInfo srcTemplate; + final TemplateInfo destTemplate; + final DataStore destStore; + final AsyncCallFuture future; + + /** + * @param callback + */ + public CopyTemplateContext(AsyncCompletionCallback callback, AsyncCallFuture future, TemplateInfo srcTemplate, + TemplateInfo destTemplate, DataStore destStore) { + super(callback); + this.srcTemplate = srcTemplate; + this.destTemplate = destTemplate; + this.destStore = destStore; + this.future = future; + } + + public TemplateInfo getSrcTemplate() { + return srcTemplate; + } + + public TemplateInfo getDestTemplate() { + return destTemplate; + } + + public DataStore getDestStore() { + return destStore; + } + + public AsyncCallFuture getFuture() { + return future; + } + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 86234c18ff0..37f0e47955e 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -41,6 +41,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; @@ -93,7 +94,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { VMTemplateDao imageDataDao; @Inject VolumeDao2 volumeDao; - @Inject + @Inject HostDao hostDao; @Inject HostPodDao podDao; @@ -119,7 +120,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { HostVO host; String primaryName = "my primary data store"; DataStore primaryStore; - + @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -137,7 +138,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { return; } //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); dc = dcDao.persist(dc); dcId = dc.getId(); @@ -172,7 +173,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { host = hostDao.persist(host); //primaryStore = createPrimaryDataStore(); - + //CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString()); /*try { @@ -188,7 +189,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { //Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); } - + @Override protected void injectMockito() { if (host == null) { @@ -225,10 +226,10 @@ public class volumeServiceTest extends CloudStackTestNGBase { image.setPrepopulate(true); image.setCrossZones(true); image.setExtractable(true); - + //image.setImageDataStoreId(storeId); image = imageDataDao.persist(image); - + return image; } @@ -237,7 +238,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { DataStore store = createImageStore(); VMTemplateVO image = createImageData(); TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store); - AsyncCallFuture future = imageService.createTemplateAsync(template, store); + AsyncCallFuture future = imageService.createTemplateAsync(template, store); future.get(); template = imageDataFactory.getTemplate(image.getId(), store); /*imageProviderMgr.configure("image Provider", new HashMap()); @@ -259,7 +260,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { public void createTemplateTest() { createTemplate(); } - + @Test public void testCreatePrimaryStorage() { DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); @@ -282,13 +283,13 @@ public class volumeServiceTest extends CloudStackTestNGBase { params.put("roles", DataStoreRole.Primary.toString()); params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString()); params.put("providerName", String.valueOf(provider.getName())); - + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); this.primaryStore = lifeCycle.initialize(params); ClusterScope scope = new ClusterScope(clusterId, podId, dcId); lifeCycle.attachCluster(this.primaryStore, scope); } - + private DataStore createImageStore() { DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider"); Map params = new HashMap(); @@ -306,7 +307,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { public void testcreateImageStore() { createImageStore(); } - + public DataStore createPrimaryDataStore() { try { @@ -324,16 +325,16 @@ public class volumeServiceTest extends CloudStackTestNGBase { params.put("roles", DataStoreRole.Primary.toString()); params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString()); params.put("providerName", String.valueOf(provider.getName())); - + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); DataStore store = lifeCycle.initialize(params); ClusterScope scope = new ClusterScope(clusterId, podId, dcId); lifeCycle.attachCluster(store, scope); - + /* PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); primaryDataStoreProviderMgr.configure("primary data store mgr", new HashMap()); - + List ds = primaryStoreDao.findPoolByName(this.primaryName); if (ds.size() >= 1) { PrimaryDataStoreVO store = ds.get(0); @@ -341,8 +342,8 @@ public class volumeServiceTest extends CloudStackTestNGBase { return provider.getDataStore(store.getId()); } } - - + + Map params = new HashMap(); params.put("url", this.getPrimaryStorageUrl()); params.put("dcId", dcId.toString()); @@ -385,8 +386,8 @@ public class volumeServiceTest extends CloudStackTestNGBase { e.printStackTrace(); } } - - //@Test(priority=3) + + //@Test(priority=3) public void createDataDisk() { DataStore primaryStore = this.primaryStore; VolumeVO volume = createVolume(null, primaryStore.getId()); @@ -402,8 +403,8 @@ public class volumeServiceTest extends CloudStackTestNGBase { e.printStackTrace(); } } - - //@Test(priority=3) + + //@Test(priority=3) public void createAndDeleteDataDisk() { DataStore primaryStore = this.primaryStore; VolumeVO volume = createVolume(null, primaryStore.getId()); @@ -418,7 +419,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { // TODO Auto-generated catch block e.printStackTrace(); } - + //delete the volume vol = volumeFactory.getVolume(volume.getId(), primaryStore); future = volumeService.expungeVolumeAsync(vol); diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 8906eaf9c62..34efdcb40ca 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -36,6 +36,7 @@ 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.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -180,7 +181,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te throw new CloudRuntimeException("Unable to find image store to download template "+ profile.getTemplate()); } for (DataStore imageStore : imageStores) { - AsyncCallFuture future = this.imageService + AsyncCallFuture future = this.imageService .createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore); try { future.get(); @@ -226,10 +227,10 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te for (DataStore imageStore : imageStores) { s_logger.info("Delete template from image store: " + imageStore.getName()); - AsyncCallFuture future = this.imageService + AsyncCallFuture future = this.imageService .deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore)); try { - CommandResult result = future.get(); + TemplateApiResult result = future.get(); success = result.isSuccess(); if ( !success ) break; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 619cd7ece4c..21d3f06725c 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -64,6 +64,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -945,49 +947,63 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Transaction txn = Transaction.currentTxn(); txn.start(); - //Copy will just find one eligible image store for the destination zone and copy template there, not propagate to all image stores + TemplateInfo srcTemplate = this.tmplFactory.getTemplate(template.getId(), srcSecStore); + // Copy will just find one eligible image store for the destination zone + // and copy template there, not propagate to all image stores // for that zone - for ( DataStore dstSecStore : dstSecStores ) { + for (DataStore dstSecStore : dstSecStores) { TemplateDataStoreVO dstTmpltStore = null; try { - dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId, true); - if (dstTmpltStore != null) { - dstTmpltStore = _tmplStoreDao.lockRow(dstTmpltStore.getId(), true); - if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) { - if (dstTmpltStore.getDestroyed() == false) { - return true; // already downloaded on this image store - } else { - dstTmpltStore.setDestroyed(false); - _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); - return true; - } - } else if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOAD_ERROR){ - if (dstTmpltStore.getDestroyed() == true) { - dstTmpltStore.setDestroyed(false); - dstTmpltStore.setDownloadState(Status.NOT_DOWNLOADED); - dstTmpltStore.setDownloadPercent(0); - dstTmpltStore.setCopy(true); - dstTmpltStore.setErrorString(""); - dstTmpltStore.setJobId(null); - _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); - } - } - } + dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId, true); + if (dstTmpltStore != null) { + dstTmpltStore = _tmplStoreDao.lockRow(dstTmpltStore.getId(), true); + if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) { + if (dstTmpltStore.getDestroyed() == false) { + return true; // already downloaded on this image + // store + } else { + dstTmpltStore.setDestroyed(false); + _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); + return true; + } + } else if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOAD_ERROR) { + if (dstTmpltStore.getDestroyed() == true) { + dstTmpltStore.setDestroyed(false); + dstTmpltStore.setDownloadState(Status.NOT_DOWNLOADED); + dstTmpltStore.setDownloadPercent(0); + dstTmpltStore.setCopy(true); + dstTmpltStore.setErrorString(""); + dstTmpltStore.setJobId(null); + _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); + } + } + } } finally { - txn.commit(); + txn.commit(); } - if(_downloadMonitor.copyTemplate(template, srcSecStore, dstSecStore) ) { + AsyncCallFuture future = this.tmpltSvr.copyTemplate(srcTemplate, dstSecStore); + try { + TemplateApiResult result = future.get(); + if (result.isFailed()) { + s_logger.debug("copy template failed:" + result.getResult()); + return false; + } + // if(_downloadMonitor.copyTemplate(template, srcSecStore, + // dstSecStore) ) { _tmpltDao.addTemplateToZone(template, dstZoneId); - if(account.getId() != Account.ACCOUNT_ID_SYSTEM){ + if (account.getId() != Account.ACCOUNT_ID_SYSTEM) { UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltStore.getSize(), template.getClass().getName(), template.getUuid()); - } - return true; + } + return true; + } catch (Exception ex) { + s_logger.debug("failed to copy template to image store:" + dstSecStore.getName() + " ,will try next one"); } } return false; + } @@ -1002,17 +1018,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Long destZoneId = cmd.getDestinationZoneId(); Account caller = UserContext.current().getCaller(); - /* - if (_swiftMgr.isSwiftEnabled()) { - throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones"); - } - - if (_s3Mgr.isS3Enabled()) { - throw new CloudRuntimeException( - "copytemplate API is disabled in S3 setup -- S3 templates are accessible in all zones."); - } - */ - //Verify parameters if (sourceZoneId == destZoneId) { throw new InvalidParameterValueException("Please specify different source and destination zones."); @@ -1769,7 +1774,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (store.size() > 1) { throw new CloudRuntimeException("muliple image data store, don't know which one to use"); } - AsyncCallFuture future = null; + AsyncCallFuture future = null; if (snapshotId != null) { SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId); future = this.tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); From 0229c75b50a008a86ded801ff98617adb24c56da Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sat, 20 Apr 2013 20:44:31 -0700 Subject: [PATCH 041/303] Use data motion service for PrepareTemplateCmd to move template from secondary storage to primary. --- .../api/storage/TemplateService.java | 5 +- .../storage/image/TemplateServiceImpl.java | 74 +++++++++- .../cloud/template/TemplateManagerImpl.java | 132 ++++++------------ 3 files changed, 121 insertions(+), 90 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index 2fc6d3d1f1e..d7010fd9e2f 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.StoragePool; public interface TemplateService { @@ -43,8 +44,8 @@ public interface TemplateService { AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); AsyncCallFuture deleteTemplateAsync(TemplateInfo template); - AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, - DataStore destStore); + AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore); + AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool ); void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId); void handleTemplateSync(DataStore store); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index ccdcc5ac516..04003bfb577 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -74,12 +74,14 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; @@ -87,6 +89,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @@ -132,6 +135,7 @@ public class TemplateServiceImpl implements TemplateService { VolumeDao _volumeDao; @Inject TemplateDataFactory _templateFactory; + @Inject VMTemplatePoolDao _tmpltPoolDao; @@ -559,7 +563,7 @@ public class TemplateServiceImpl implements TemplateService { .setContext(context); this._motionSrv.copyAsync(srcTemplate, destTemplate, caller); } catch (Exception e) { - s_logger.debug("Failed to copy volume", e); + s_logger.debug("Failed to copy template", e); res.setResult(e.toString()); future.complete(res); } @@ -597,6 +601,74 @@ public class TemplateServiceImpl implements TemplateService { return null; } + protected Void prepareTemplateCallBack(AsyncCallbackDispatcher callback, + CopyTemplateContext context) { + TemplateInfo srcTemplate = context.getSrcTemplate(); + TemplateInfo destTemplate = context.getDestTemplate(); + CopyCommandResult result = callback.getResult(); + AsyncCallFuture future = context.getFuture(); + TemplateApiResult res = new TemplateApiResult(destTemplate); + try { + if (result.isFailed()) { + res.setResult(result.getResult()); + destTemplate.processEvent(Event.OperationFailed); + srcTemplate.processEvent(Event.OperationFailed); + // remove entry from template_spool_ref + VMTemplateStoragePoolVO destTmpltPool = _tmpltPoolDao.findByPoolTemplate(context.getDestStore().getId(), destTemplate.getId()); + _vmTemplateStoreDao.remove(destTmpltPool.getId()); + future.complete(res); + return null; + } + srcTemplate.processEvent(Event.OperationSuccessed); + // update other information in template_spool_ref through templateObject event processing. + destTemplate.processEvent(Event.OperationSuccessed); + future.complete(res); + return null; + } catch (Exception e) { + s_logger.debug("Failed to process prepare template callback", e); + res.setResult(e.toString()); + future.complete(res); + } + + return null; + } + + @Override + public AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool) { + AsyncCallFuture future = new AsyncCallFuture(); + TemplateApiResult res = new TemplateApiResult(srcTemplate); + long poolId = pool.getId(); + long templateId = srcTemplate.getId(); + try{ + // create one entry in template_spool_ref + VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); + if (templateStoragePoolRef == null) { + templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId); + templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef); + } + DataStore destStore = (DataStore)pool; + TemplateInfo destTemplate = this._templateFactory.getTemplate(templateStoragePoolRef.getTemplateId(), destStore); + destTemplate.processEvent(Event.CreateOnlyRequested); + srcTemplate.processEvent(Event.CopyingRequested); + + CopyTemplateContext context = new CopyTemplateContext(null, future, srcTemplate, + destTemplate, + destStore + ); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().prepareTemplateCallBack(null, null)) + .setContext(context); + this._motionSrv.copyAsync(srcTemplate, destTemplate, caller); + } catch (Exception e) { + s_logger.debug("Failed to prepare template on storage pool", e); + res.setResult(e.toString()); + future.complete(res); + } + return future; + } + + + class CopyTemplateContext extends AsyncRpcConext { final TemplateInfo srcTemplate; final TemplateInfo destTemplate; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 21d3f06725c..a8d524b7cb5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -666,7 +666,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, long templateId = template.getId(); long dcId = pool.getDataCenterId(); VMTemplateStoragePoolVO templateStoragePoolRef = null; - VMTemplateHostVO templateHostRef = null; + TemplateDataStoreVO templateStoreRef = null; long templateStoragePoolRefId; String origUrl = null; @@ -684,113 +684,71 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - templateHostRef = findVmTemplateHost(templateId, pool); + templateStoreRef = findVmTemplateImageStore(templateId, pool); - if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) { - String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId); - if (result != null) { - s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); - return null; - } - result = _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(dcId, - templateId, _primaryStorageDownloadWait); - if (result != null) { - s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); - return null; - } - templateHostRef = findVmTemplateHost(templateId, pool); - if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) { - s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); - return null; - } + if (templateStoreRef == null) { + s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); + return null; } - HostVO sh = _hostDao.findById(templateHostRef.getHostId()); + List vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up); + if (vos == null || vos.isEmpty()){ + throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool"); + } + + /* + HostVO sh = _hostDao.findById(templateStoreRef.getHostId()); origUrl = sh.getStorageUrl(); if (origUrl == null) { throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString()); } + */ if (templateStoragePoolRef == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Downloading template " + templateId + " to pool " + poolId); } - templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId); + DataStore srcSecStore = this.dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image); + TemplateInfo srcTemplate = this.tmplFactory.getTemplate(templateId, srcSecStore); + + AsyncCallFuture future = this.tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool); try { - templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef); - templateStoragePoolRefId = templateStoragePoolRef.getId(); - - } catch (Exception e) { - s_logger.debug("Assuming we're in a race condition: " + e.getMessage()); - templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); - if (templateStoragePoolRef == null) { - throw new CloudRuntimeException("Unable to persist a reference for pool " + poolId + " and template " + templateId); + TemplateApiResult result = future.get(); + if (result.isFailed()) { + s_logger.debug("prepare template failed:" + result.getResult()); + return null; } - templateStoragePoolRefId = templateStoragePoolRef.getId(); + + return _tmpltPoolDao.findByPoolTemplate(poolId, templateId); } - } else { - templateStoragePoolRefId = templateStoragePoolRef.getId(); - } - - List vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up); - if (vos == null || vos.isEmpty()){ - throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool"); - } - - templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds); - if (templateStoragePoolRef == null) { - throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId); - } - - try { - if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) { - return templateStoragePoolRef; + catch (Exception ex) { + s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage"); } - String url = origUrl + "/" + templateHostRef.getInstallPath(); - PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(), - template.getAccountId(), pool, _primaryStorageDownloadWait); - HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId()); - assert(secondaryStorageHost != null); - dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl()); - - - for (int retry = 0; retry < 2; retry ++){ - Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries - StoragePoolHostVO vo = vos.get(0); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Downloading " + templateId + " via " + vo.getHostId()); - } - dcmd.setLocalPath(vo.getLocalPath()); - // set 120 min timeout for this command - - PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend( - _hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd); - if (answer != null && answer.getResult() ) { - templateStoragePoolRef.setDownloadPercent(100); - templateStoragePoolRef.setDownloadState(Status.DOWNLOADED); - templateStoragePoolRef.setLocalDownloadPath(answer.getInstallPath()); - templateStoragePoolRef.setInstallPath(answer.getInstallPath()); - templateStoragePoolRef.setTemplateSize(answer.getTemplateSize()); - _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Template " + templateId + " is downloaded via " + vo.getHostId()); - } - return templateStoragePoolRef; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Template " + templateId + " download to pool " + vo.getPoolId() + " failed due to " + (answer!=null?answer.getDetails():"return null")); } - } - } - } finally { - _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Template " + templateId + " is not found on and can not be downloaded to pool " + poolId); } + return null; } + private TemplateDataStoreVO findVmTemplateImageStore(long templateId, + StoragePool pool) { + long dcId = pool.getDataCenterId(); + List secStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId)); + + if ( secStores == null ){ + s_logger.error("No image store found to download template " + templateId + " primary storage!"); + return null; + } + for (DataStore store : secStores ){ + List templStores = this._tmplStoreDao.listByTemplateStoreDownloadStatus(templateId, store.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (templStores != null && !templStores.isEmpty()) { + Collections.shuffle(templStores); + return templStores.get(0); + } + } + + return null; + } @Override From abf40435f3cb1d72535eb15067348e4c9253340d Mon Sep 17 00:00:00 2001 From: Edison Su Date: Sun, 21 Apr 2013 22:46:02 -0700 Subject: [PATCH 042/303] refactor downloadlistener, sync system vm templates when adding a new image store --- .../src/com/cloud/agent/Listener.java | 4 +- .../subsystem/api/storage/EndPoint.java | 2 + .../api/storage/TemplateService.java | 3 +- .../StorageCacheRandomAllocator.java | 2 + .../manager/StorageCacheManagerImpl.java | 23 +- .../storage/image/TemplateServiceImpl.java | 73 ++--- .../storage/image/store/TemplateObject.java | 31 +- .../storage/test/volumeServiceTest.java | 4 +- .../cloudstack/storage/LocalHostEndpoint.java | 48 ++- .../storage/RemoteHostEndPoint.java | 49 ++- .../datastore/ObjectInDataStoreManager.java | 1 - .../ObjectInDataStoreManagerImpl.java | 35 +-- .../storage/volume/VolumeObject.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 9 +- .../cloud/resource/SimulatorDiscoverer.java | 3 +- .../SimulatorSecondaryDiscoverer.java | 3 +- .../vmware/manager/VmwareManagerImpl.java | 3 +- .../xen/discoverer/XcpServerDiscoverer.java | 2 +- .../CloudStackImageStoreDriverImpl.java | 65 +++- .../driver/S3ImageStoreDriverImpl.java | 6 +- .../driver/SwiftImageStoreDriverImpl.java | 6 +- server/pom.xml | 5 + .../com/cloud/agent/manager/AgentMonitor.java | 2 +- .../agent/manager/SynchronousListener.java | 4 +- .../com/cloud/capacity/CapacityManager.java | 3 +- .../cloud/capacity/CapacityManagerImpl.java | 13 +- .../capacity/ComputeCapacityListener.java | 4 +- .../capacity/StorageCapacityListener.java | 4 +- .../AgentBasedConsoleProxyManager.java | 4 +- .../src/com/cloud/consoleproxy/AgentHook.java | 4 +- .../consoleproxy/ConsoleProxyListener.java | 4 +- .../consoleproxy/ConsoleProxyManager.java | 4 +- .../consoleproxy/ConsoleProxyManagerImpl.java | 2 +- .../discoverer/LibvirtServerDiscoverer.java | 2 +- .../com/cloud/network/NetworkManagerImpl.java | 3 +- .../network/NetworkUsageManagerImpl.java | 2 +- .../cloud/network/SshKeysDistriMonitor.java | 4 +- .../VirtualNetworkApplianceManagerImpl.java | 3 +- .../security/SecurityGroupListener.java | 4 +- .../storage/LocalStoragePoolListener.java | 4 +- .../download/DownloadAbandonedState.java | 4 +- .../storage/download/DownloadActiveState.java | 2 +- .../storage/download/DownloadErrorState.java | 6 +- .../storage/download/DownloadListener.java | 286 ++---------------- .../storage/download/DownloadMonitor.java | 22 +- .../storage/download/DownloadMonitorImpl.java | 166 +++------- .../cloud/storage/download/DownloadState.java | 2 +- .../storage/listener/StoragePoolMonitor.java | 4 +- .../storage/listener/StorageSyncListener.java | 4 +- .../secondary/SecondaryStorageListener.java | 4 +- .../cloud/storage/upload/UploadListener.java | 3 +- .../template/HypervisorTemplateAdapter.java | 46 ++- .../cloud/vm/VirtualMachineManagerImpl.java | 2 +- 53 files changed, 417 insertions(+), 583 deletions(-) rename {core => api}/src/com/cloud/agent/Listener.java (96%) diff --git a/core/src/com/cloud/agent/Listener.java b/api/src/com/cloud/agent/Listener.java similarity index 96% rename from core/src/com/cloud/agent/Listener.java rename to api/src/com/cloud/agent/Listener.java index 47b9bc3011d..3b825bd7b4e 100755 --- a/core/src/com/cloud/agent/Listener.java +++ b/api/src/com/cloud/agent/Listener.java @@ -22,7 +22,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; /** @@ -72,7 +72,7 @@ public interface Listener { * @param agentId id of the agent * @throws ConnectionException if host has problems and needs to put into maintenance state. */ - void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException; + void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException; /** * This method is called by AgentManager when an agent disconnects diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java index 2ff45b1bf56..eb6da701208 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -25,4 +26,5 @@ public interface EndPoint { public long getId(); public Answer sendMessage(Command cmd); public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); + void sendMessageAsyncWithListener(Command cmd, Listener listner); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index d7010fd9e2f..f04b14df050 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -40,7 +41,7 @@ public interface TemplateService { } - AsyncCallFuture createTemplateAsync(TemplateInfo template, DataStore store); + void createTemplateAsync(TemplateInfo template, DataStore store, AsyncCompletionCallback callback); AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); AsyncCallFuture deleteTemplateAsync(TemplateInfo template); 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 index c357d239026..462f13fca77 100644 --- 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 @@ -25,12 +25,14 @@ 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 org.springframework.stereotype.Component; import com.cloud.storage.ScopeType; import com.cloud.utils.exception.CloudRuntimeException; import edu.emory.mathcs.backport.java.util.Collections; +@Component public class StorageCacheRandomAllocator implements StorageCacheAllocator { @Inject DataStoreManager dataStoreMgr; 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 index 150c28930f5..47fe4890220 100644 --- 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 @@ -37,6 +37,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.log4j.Logger; import com.cloud.utils.component.Manager; @@ -115,11 +116,11 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { private class CreateCacheObjectContext extends AsyncRpcConext { - final AsyncCallFuture future; + final AsyncCallFuture future; /** * @param callback */ - public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { + public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { super(callback); this.future = future; } @@ -130,22 +131,22 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - AsyncCallFuture future = new AsyncCallFuture(); - CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallFuture future = new AsyncCallFuture(); + CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - CommandResult result = null; + CopyCmdAnswer result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); dataMotionSvr.copyAsync(data, objOnCacheStore, caller); result = future.get(); - if (result.isFailed()) { + if (!result.getResult()) { cacheStore.delete(data); } else { - objOnCacheStore.processEvent(Event.OperationSuccessed); + objOnCacheStore.processEvent(Event.OperationSuccessed, result); } } catch (InterruptedException e) { s_logger.debug("create cache storage failed: " + e.toString()); @@ -162,9 +163,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return null; } - protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, - CreateCacheObjectContext context) { - AsyncCallFuture future = context.future; + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, + CreateCacheObjectContext context) { + AsyncCallFuture future = context.future; future.complete(callback.getResult()); return null; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 04003bfb577..0057012945a 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -34,19 +34,15 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; 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.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; - -import com.cloud.storage.template.TemplateProp; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -71,25 +67,22 @@ import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @@ -137,15 +130,11 @@ public class TemplateServiceImpl implements TemplateService { TemplateDataFactory _templateFactory; @Inject VMTemplatePoolDao _tmpltPoolDao; - - - class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; final AsyncCallFuture future; - public TemplateOpContext(AsyncCompletionCallback callback, TemplateObject template, - AsyncCallFuture future) { + AsyncCallFuture future) { super(callback); this.template = template; this.future = future; @@ -154,30 +143,22 @@ public class TemplateServiceImpl implements TemplateService { public TemplateObject getTemplate() { return template; } - - public AsyncCallFuture getFuture() { - return future; - } - - } @Override - public AsyncCallFuture createTemplateAsync( - TemplateInfo template, DataStore store) { - AsyncCallFuture future = new AsyncCallFuture(); + public void createTemplateAsync( + TemplateInfo template, DataStore store, AsyncCompletionCallback callback) { // persist template_store_ref entry DataObject templateOnStore = store.create(template); // update template_store_ref state templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); - TemplateOpContext context = new TemplateOpContext(null, - (TemplateObject)templateOnStore, future); + TemplateOpContext context = new TemplateOpContext(callback, + (TemplateObject)templateOnStore, null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createTemplateCallback(null, null)).setContext(context); store.getDriver().createAsync(templateOnStore, caller); - return future; } @Override @@ -185,26 +166,20 @@ public class TemplateServiceImpl implements TemplateService { Set toBeDownloaded = new HashSet(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); for (VMTemplateVO rtngTmplt : rtngTmplts) { toBeDownloaded.add(rtngTmplt); } - for (VMTemplateVO builtinTmplt : defaultBuiltin) { - toBeDownloaded.add(builtinTmplt); - } - for (VMTemplateVO template : toBeDownloaded) { TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { - _dlMonitor.downloadBootstrapSysTemplateToStorage(template, store, null); + TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId()); + this.createTemplateAsync(tmplt, store, null); } } } - - - + @Override public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { Set toBeDownloaded = new HashSet(); @@ -234,16 +209,13 @@ public class TemplateServiceImpl implements TemplateService { for (VMTemplateVO template: toBeDownloaded) { TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(ssHost.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { - _dlMonitor.downloadTemplateToStorage(template, ssHost, null); + DataObject tmpl = this._templateFactory.getTemplate(template.getId(), ssHost); + _dlMonitor.downloadTemplateToStorage(tmpl, ssHost, null); } } } } - - - - @Override public void handleTemplateSync(DataStore store) { if (store == null) { @@ -394,7 +366,8 @@ public class TemplateServiceImpl implements TemplateService { } s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName()); //TODO: we should pass a callback here - _dlMonitor.downloadTemplateToStorage(tmplt, store, null); + DataObject tmpl = this._templateFactory.getTemplate(tmplt.getId(), store); + _dlMonitor.downloadTemplateToStorage(tmpl, store, null); } } } @@ -465,9 +438,9 @@ public class TemplateServiceImpl implements TemplateService { protected Void createTemplateCallback(AsyncCallbackDispatcher callback, - TemplateOpContext context) { + TemplateOpContext context) { TemplateObject template = (TemplateObject)context.getTemplate(); - AsyncCallFuture future = context.getFuture(); + AsyncCompletionCallback parentCallback = context.getParentCallback(); TemplateApiResult result = new TemplateApiResult(template); CreateCmdResult callbackResult = callback.getResult(); if (callbackResult.isFailed()) { @@ -478,7 +451,7 @@ public class TemplateServiceImpl implements TemplateService { s_logger.debug("Failed to update template state", e); } result.setResult(callbackResult.getResult()); - future.complete(result); + parentCallback.complete(result); return null; } @@ -488,11 +461,11 @@ public class TemplateServiceImpl implements TemplateService { } catch (NoTransitionException e) { s_logger.debug("Failed to transit state", e); result.setResult(e.toString()); - future.complete(result); + parentCallback.complete(result); return null; } - future.complete(result); + parentCallback.complete(result); return null; } @@ -520,7 +493,7 @@ public class TemplateServiceImpl implements TemplateService { } else { vo.processEvent(Event.OperationFailed); } - context.getFuture().complete(result); + context.future.complete(result); return null; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 15aad4ba3e7..3230724ba8c 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -29,13 +29,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.utils.component.ComponentContext; @@ -54,6 +60,7 @@ public class TemplateObject implements TemplateInfo { @Inject ObjectInDataStoreManager ojbectInStoreMgr; @Inject VMTemplatePoolDao templatePoolDao; + @Inject TemplateDataStoreDao templateStoreDao; public TemplateObject() { } @@ -163,7 +170,7 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(Event event) { try { - ojbectInStoreMgr.update(this, event, null); + ojbectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); @@ -173,7 +180,27 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { - ojbectInStoreMgr.update(this, event, answer); + if (this.getDataStore().getRole() == DataStoreRole.Primary) { + if (answer != null && answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId()); + templatePoolRef.setDownloadPercent(100); + templatePoolRef.setDownloadState(Status.DOWNLOADED); + templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); + templatePoolRef.setInstallPath(cpyAnswer.getPath()); + templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); + } + } else if (this.getDataStore().getRole() == DataStoreRole.Image || + this.getDataStore().getRole() == DataStoreRole.ImageCache) { + if (answer != null && answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(), + this.getId()); + templateStoreRef.setInstallPath(cpyAnswer.getPath()); + templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); + } + } + ojbectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 37f0e47955e..e47eaec92eb 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -238,8 +238,8 @@ public class volumeServiceTest extends CloudStackTestNGBase { DataStore store = createImageStore(); VMTemplateVO image = createImageData(); TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store); - AsyncCallFuture future = imageService.createTemplateAsync(template, store); - future.get(); + //AsyncCallFuture future = imageService.createTemplateAsync(template, store); + //future.get(); template = imageDataFactory.getTemplate(image.getId(), store); /*imageProviderMgr.configure("image Provider", new HashMap()); VMTemplateVO image = createImageData(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 665ed92ef54..f08a5977b2e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -1,20 +1,28 @@ package org.apache.cloudstack.storage; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCmd; +import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.resource.ServerResource; +import com.cloud.storage.download.DownloadListener; import com.cloud.storage.resource.LocalNfsSecondaryStorageResource; import com.cloud.utils.component.ComponentContext; public class LocalHostEndpoint implements EndPoint { - + private ScheduledExecutorService executor; ServerResource resource; public LocalHostEndpoint() { resource = ComponentContext.inject(LocalNfsSecondaryStorageResource.class); + executor = Executors.newScheduledThreadPool(10); } @Override public long getId() { @@ -31,11 +39,45 @@ public class LocalHostEndpoint implements EndPoint { return new Answer(cmd, false, "unsupported command:" + cmd.toString()); } + private class CmdRunner implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; + public CmdRunner(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + @Override + public void run() { + Answer answer = sendMessage(cmd); + callback.complete(answer); + } + } + + private class CmdRunner2 implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; + public CmdRunner2(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + @Override + public void run() { + DownloadAnswer answer = (DownloadAnswer)sendMessage(cmd); + callback.complete(answer); + } + } @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - + executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); + } + + @Override + public void sendMessageAsyncWithListener(Command cmd, Listener listner) { + if (listner instanceof DownloadListener) { + DownloadListener listener = (DownloadListener)listner; + executor.schedule(new CmdRunner2(cmd, listener.getCallback()), 10, TimeUnit.SECONDS); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index aec7b520391..9ce4e759fc9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -18,6 +18,10 @@ */ package org.apache.cloudstack.storage; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; @@ -25,11 +29,14 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; +import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.manager.Commands; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.OperationTimedoutException; import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.exception.CloudRuntimeException; public class RemoteHostEndPoint implements EndPoint { private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class); @@ -39,9 +46,10 @@ public class RemoteHostEndPoint implements EndPoint { AgentManager agentMgr; @Inject HostEndpointRpcServer rpcServer; + private ScheduledExecutorService executor; protected RemoteHostEndPoint() { - + executor = Executors.newScheduledThreadPool(10); } private void configure(long hostId, String hostAddress) { @@ -65,11 +73,46 @@ public class RemoteHostEndPoint implements EndPoint { @Override public Answer sendMessage(Command cmd) { - return rpcServer.sendCommand(this, cmd); + String errMsg = null; + try { + return agentMgr.send(getId(), cmd); + } catch (AgentUnavailableException e) { + errMsg = e.toString(); + s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); + } catch (OperationTimedoutException e) { + errMsg = e.toString(); + s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); + } + throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg); } + private class CmdRunner implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; + public CmdRunner(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + @Override + public void run() { + Answer answer = sendMessage(cmd); + callback.complete(answer); + } + + } + @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { - rpcServer.sendCommandAsync(this, cmd, callback); + executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); + } + + @Override + public void sendMessageAsyncWithListener(Command cmd, Listener listener) { + try { + this.agentMgr.send(getId(), new Commands(cmd), listener); + } catch (AgentUnavailableException e) { + s_logger.debug("Failed to send command: " + e.toString()); + throw new CloudRuntimeException("Failed to send command: " + e.toString()); + } } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index 876a06694b5..d53029a3474 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -29,7 +29,6 @@ import com.cloud.utils.fsm.NoTransitionException; public interface ObjectInDataStoreManager { public DataObject create(DataObject template, DataStore dataStore); public DataObject get(DataObject dataObj, DataStore store); - public boolean update(DataObject vo, Event event, Answer answer) throws NoTransitionException; public boolean update(DataObject vo, Event event) throws NoTransitionException; DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 52ed312c0d9..bf9a98d08f7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -23,12 +23,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -40,15 +39,12 @@ import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.api.Answer; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; @@ -162,7 +158,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } @Override - public boolean update(DataObject data, Event event, Answer answer) + public boolean update(DataObject data, Event event) throws NoTransitionException { DataObjectInStore obj = this.findObject(data, data.getDataStore()); if (obj == null) { @@ -171,7 +167,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { + data); } - if ( data.getDataStore().getRole() == DataStoreRole.Image){ + if ( data.getDataStore().getRole() == DataStoreRole.Image || data.getDataStore().getRole() == DataStoreRole.ImageCache){ switch (data.getType()){ case TEMPLATE: this.stateMachines.transitTo(obj, event, null, templateDataStoreDao); @@ -181,22 +177,10 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao); } } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { - if (answer != null && answer instanceof CopyCmdAnswer) { - CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; - VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(data.getDataStore().getId(), data.getId()); - templatePoolRef.setDownloadPercent(100); - templatePoolRef.setDownloadState(Status.DOWNLOADED); - templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); - templatePoolRef.setInstallPath(cpyAnswer.getPath()); - templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); - } - try { - obj = this.findObject(data, data.getDataStore()); - this.stateMachines.transitTo(obj, event, null, - templatePoolDao); - } catch (NoTransitionException e) { - throw e; - } + + this.stateMachines.transitTo(obj, event, null, + templatePoolDao); + } else { throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); } @@ -273,9 +257,4 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return store; } - @Override - public boolean update(DataObject vo, Event event) throws NoTransitionException { - return this.update(vo, event, null); - } - } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 34e080d5d52..2834ed03407 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -165,7 +165,7 @@ public class VolumeObject implements VolumeInfo { try { Volume.Event volEvent = null; if (this.dataStore.getRole() == DataStoreRole.Image) { - ojbectInStoreMgr.update(this, event, null); + ojbectInStoreMgr.update(this, event); if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { volEvent = Volume.Event.UploadRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index d4087ed66f3..42c61f391a5 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -58,14 +58,14 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; +import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; import com.cloud.storage.StoragePool; -import com.cloud.storage.Volume; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; @@ -659,6 +659,9 @@ public class VolumeServiceImpl implements VolumeService { } else { vo.stateTransit(Volume.Event.OperationSucceeded); }*/ + + _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, + vo.getSize()); VolumeApiResult res = new VolumeApiResult(vo); context.future.complete(res); return null; @@ -805,7 +808,7 @@ public class VolumeServiceImpl implements VolumeService { } s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName()); //TODO: pass a callback later - _dlMonitor.downloadVolumeToStorage(_volumeDao.findById(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); + _dlMonitor.downloadVolumeToStorage(this.volFactory.getVolume(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); } } diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java index 00fe356103b..a9f61341c9d 100755 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java @@ -44,6 +44,7 @@ import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.ConnectionException; import com.cloud.exception.DiscoveryException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -255,7 +256,7 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { /*if(forRebalance) return; diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java index 3a8cf17e24b..6bbd90f986f 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java @@ -36,6 +36,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.manager.MockStorageManager; import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.storage.SnapshotVO; @@ -158,7 +159,7 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp } @Override - public void processConnect(HostVO host, StartupCommand cmd, + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index b2e37685d17..ba99da11996 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -54,6 +54,7 @@ import com.cloud.dc.ClusterVSMMapVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.ClusterVSMMapDao; import com.cloud.exception.DiscoveredWithErrorException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -757,7 +758,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { if(cmd instanceof StartupCommand) { if(host.getHypervisorType() == HypervisorType.VMware) { updateClusterNativeHAState(host, cmd); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 89bc1cf5708..195ab309872 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -555,7 +555,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(com.cloud.host.Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand )) { return; } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index fe556a2401d..0c078b1e316 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.util.Date; import java.util.List; import java.util.Set; @@ -32,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -48,6 +50,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; @@ -155,21 +158,73 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } } + private class createObjectContext extends AsyncRpcConext { + final DataObject data; + public createObjectContext(AsyncCompletionCallback callback, DataObject data) { + super(callback); + this.data = data; + } + + } @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { + createObjectContext context = new createObjectContext(callback, data); + AsyncCallbackDispatcher caller = + AsyncCallbackDispatcher.create(this); + caller.setContext(context); + caller.setCallback(callback); + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); + _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); } + } + + protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + createObjectContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); - CreateCmdResult result = new CreateCmdResult(null, null); - callback.complete(result); + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(store.getId(), updateBuilder); + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSucess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + if (answer.getCheckSum() != null) { + VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); + templateDaoBuilder.setChecksum(answer.getCheckSum()); + templateDao.update(obj.getId(), templateDaoBuilder); + } + + + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; } private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 10734673e4e..6f5d554dac6 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -164,12 +164,12 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); + _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 88405d284ba..1b9ab2d485a 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -157,12 +157,12 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData.getImage(), tData.getDataStore(), callback); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo.getVolume(), volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), callback); + _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null); } CreateCmdResult result = new CreateCmdResult(null, null); diff --git a/server/pom.xml b/server/pom.xml index a3971954475..a74450698ba 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -98,6 +98,11 @@ cloud-framework-events ${project.version} + + org.apache.cloudstack + cloud-framework-ipc + ${project.version} + install diff --git a/server/src/com/cloud/agent/manager/AgentMonitor.java b/server/src/com/cloud/agent/manager/AgentMonitor.java index f3f6669dae6..2c0266e6689 100755 --- a/server/src/com/cloud/agent/manager/AgentMonitor.java +++ b/server/src/com/cloud/agent/manager/AgentMonitor.java @@ -248,7 +248,7 @@ public class AgentMonitor extends Thread implements AgentMonitorService { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { if (host.getType().equals(Host.Type.TrafficMonitor) || host.getType().equals(Host.Type.SecondaryStorage)) { return; diff --git a/server/src/com/cloud/agent/manager/SynchronousListener.java b/server/src/com/cloud/agent/manager/SynchronousListener.java index 074f5a84820..36987053a0f 100755 --- a/server/src/com/cloud/agent/manager/SynchronousListener.java +++ b/server/src/com/cloud/agent/manager/SynchronousListener.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.utils.Profiler; @@ -79,7 +79,7 @@ public class SynchronousListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { } @Override diff --git a/server/src/com/cloud/capacity/CapacityManager.java b/server/src/com/cloud/capacity/CapacityManager.java index bdd9ccd155b..ab02e77ac19 100755 --- a/server/src/com/cloud/capacity/CapacityManager.java +++ b/server/src/com/cloud/capacity/CapacityManager.java @@ -18,6 +18,7 @@ package com.cloud.capacity; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.utils.component.Manager; @@ -41,7 +42,7 @@ public interface CapacityManager extends Manager { */ boolean checkIfHostHasCapacity(long hostId, Integer cpu, long ram, boolean checkFromReservedCapacity, float cpuOverprovisioningFactor, float memoryOvercommitRatio, boolean considerReservedCapacity); - void updateCapacityForHost(HostVO host); + void updateCapacityForHost(Host host); /** * @param pool storage pool diff --git a/server/src/com/cloud/capacity/CapacityManagerImpl.java b/server/src/com/cloud/capacity/CapacityManagerImpl.java index 292ef0abd5c..7e9ff37c513 100755 --- a/server/src/com/cloud/capacity/CapacityManagerImpl.java +++ b/server/src/com/cloud/capacity/CapacityManagerImpl.java @@ -28,12 +28,6 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import com.cloud.dc.ClusterDetailsDao; -import com.cloud.dc.DataCenter; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.resource.ResourceState; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -50,7 +44,10 @@ import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -521,7 +518,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, @DB @Override - public void updateCapacityForHost(HostVO host){ + public void updateCapacityForHost(Host host){ // prepare the service offerings List offerings = _offeringsDao.listAllIncludingRemoved(); Map offeringsMap = new HashMap(); @@ -784,7 +781,7 @@ public class CapacityManagerImpl extends ManagerBase implements CapacityManager, } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { // TODO Auto-generated method stub } diff --git a/server/src/com/cloud/capacity/ComputeCapacityListener.java b/server/src/com/cloud/capacity/ComputeCapacityListener.java index 16e154a80a6..7ca8fd74409 100755 --- a/server/src/com/cloud/capacity/ComputeCapacityListener.java +++ b/server/src/com/cloud/capacity/ComputeCapacityListener.java @@ -29,7 +29,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.capacity.dao.CapacityDao; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.utils.db.SearchCriteria; @@ -71,7 +71,7 @@ public class ComputeCapacityListener implements Listener { @Override - public void processConnect(HostVO server, StartupCommand startup, boolean forRebalance) throws ConnectionException { + public void processConnect(Host server, StartupCommand startup, boolean forRebalance) throws ConnectionException { if (!(startup instanceof StartupRoutingCommand)) { return; } diff --git a/server/src/com/cloud/capacity/StorageCapacityListener.java b/server/src/com/cloud/capacity/StorageCapacityListener.java index d5751a34cc9..d44e121866e 100755 --- a/server/src/com/cloud/capacity/StorageCapacityListener.java +++ b/server/src/com/cloud/capacity/StorageCapacityListener.java @@ -30,7 +30,7 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.capacity.dao.CapacityDao; import com.cloud.capacity.dao.CapacityDaoImpl; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.storage.Storage; import com.cloud.utils.db.SearchCriteria; @@ -71,7 +71,7 @@ public class StorageCapacityListener implements Listener { @Override - public void processConnect(HostVO server, StartupCommand startup, boolean forRebalance) throws ConnectionException { + public void processConnect(Host server, StartupCommand startup, boolean forRebalance) throws ConnectionException { if (!(startup instanceof StartupStorageCommand)) { return; diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 6f8575d751c..fe1dfe0ca3f 100755 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -43,6 +43,7 @@ import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -229,7 +230,7 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol } @Override - public void onAgentConnect(HostVO host, StartupCommand cmd) { + public void onAgentConnect(Host host, StartupCommand cmd) { } @Override @@ -356,4 +357,5 @@ public class AgentBasedConsoleProxyManager extends ManagerBase implements Consol @Override public void prepareStop(VirtualMachineProfile profile) { } + } diff --git a/server/src/com/cloud/consoleproxy/AgentHook.java b/server/src/com/cloud/consoleproxy/AgentHook.java index 5b6d585680c..29ec0456ac2 100644 --- a/server/src/com/cloud/consoleproxy/AgentHook.java +++ b/server/src/com/cloud/consoleproxy/AgentHook.java @@ -21,13 +21,13 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupProxyCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; public interface AgentHook { void onLoadReport(ConsoleProxyLoadReportCommand cmd); AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd); - void onAgentConnect(HostVO host, StartupCommand cmd); + void onAgentConnect(Host host, StartupCommand cmd); public void onAgentDisconnect(long agentId, Status state); public void startAgentHttpHandlerInVM(StartupProxyCommand startupCmd); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java index a3b72645794..2190dffe8c3 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyListener.java @@ -25,7 +25,7 @@ import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupProxyCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; public class ConsoleProxyListener implements Listener { @@ -64,7 +64,7 @@ public class ConsoleProxyListener implements Listener { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { _proxyMgr.onAgentConnect(host, cmd); if (cmd instanceof StartupProxyCommand) { diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java index 6ebf3bc61f4..459fda72685 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManager.java @@ -20,7 +20,7 @@ import com.cloud.agent.api.AgentControlAnswer; import com.cloud.agent.api.ConsoleAccessAuthenticationCommand; import com.cloud.agent.api.ConsoleProxyLoadReportCommand; import com.cloud.agent.api.StartupCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.host.Host.Type; import com.cloud.info.ConsoleProxyInfo; @@ -55,6 +55,6 @@ public interface ConsoleProxyManager extends Manager { public void onLoadReport(ConsoleProxyLoadReportCommand cmd); public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd); - public void onAgentConnect(HostVO host, StartupCommand cmd); + public void onAgentConnect(Host host, StartupCommand cmd); public void onAgentDisconnect(long agentId, Status state); } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index 1edd8692ec7..fa489ff7a2f 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -994,7 +994,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy } @Override - public void onAgentConnect(HostVO host, StartupCommand cmd) { + public void onAgentConnect(Host host, StartupCommand cmd) { // if (host.getType() == Type.ConsoleProxy) { // // TODO we can use this event to mark the proxy is up and // // functioning instead of diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index 75b007c87d2..c92ff500b22 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -99,7 +99,7 @@ Listener, ResourceStateAdapter { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { } @Override diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 62960116dce..ca5fb4ff817 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -92,7 +92,6 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.Host; -import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -3283,7 +3282,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand)) { return; } diff --git a/server/src/com/cloud/network/NetworkUsageManagerImpl.java b/server/src/com/cloud/network/NetworkUsageManagerImpl.java index 80f898b0d7a..3ac77f98cfd 100755 --- a/server/src/com/cloud/network/NetworkUsageManagerImpl.java +++ b/server/src/com/cloud/network/NetworkUsageManagerImpl.java @@ -481,7 +481,7 @@ public class NetworkUsageManagerImpl extends ManagerBase implements NetworkUsage } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { if (cmd instanceof StartupTrafficMonitorCommand) { long agentId = agent.getId(); s_logger.debug("Sending RecurringNetworkUsageCommand to " + agentId); diff --git a/server/src/com/cloud/network/SshKeysDistriMonitor.java b/server/src/com/cloud/network/SshKeysDistriMonitor.java index 82f72de8c3b..cd92ae66377 100755 --- a/server/src/com/cloud/network/SshKeysDistriMonitor.java +++ b/server/src/com/cloud/network/SshKeysDistriMonitor.java @@ -31,7 +31,7 @@ import com.cloud.agent.manager.Commands; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -69,7 +69,7 @@ public class SshKeysDistriMonitor implements Listener { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { if (((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.KVM || ((StartupRoutingCommand) cmd).getHypervisorType() == HypervisorType.XenServer || diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index ab91059b0f3..36fcbb798aa 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -120,6 +120,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.OperationTimedoutException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.StorageUnavailableException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -3539,7 +3540,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { UserContext context = UserContext.current(); context.setAccountId(1); List routers = _routerDao.listIsolatedByHostId(host.getId()); diff --git a/server/src/com/cloud/network/security/SecurityGroupListener.java b/server/src/com/cloud/network/security/SecurityGroupListener.java index 32452532f55..0c101f257d4 100755 --- a/server/src/com/cloud/network/security/SecurityGroupListener.java +++ b/server/src/com/cloud/network/security/SecurityGroupListener.java @@ -38,7 +38,7 @@ import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer.FailureReason; import com.cloud.agent.manager.Commands; import com.cloud.exception.AgentUnavailableException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.network.security.SecurityGroupWork.Step; import com.cloud.network.security.dao.SecurityGroupWorkDao; @@ -157,7 +157,7 @@ public class SecurityGroupListener implements Listener { @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) { if(s_logger.isInfoEnabled()) s_logger.info("Received a host startup notification"); diff --git a/server/src/com/cloud/storage/LocalStoragePoolListener.java b/server/src/com/cloud/storage/LocalStoragePoolListener.java index 244f7fbe271..088d601376c 100755 --- a/server/src/com/cloud/storage/LocalStoragePoolListener.java +++ b/server/src/com/cloud/storage/LocalStoragePoolListener.java @@ -32,7 +32,7 @@ import com.cloud.agent.api.StoragePoolInfo; import com.cloud.capacity.dao.CapacityDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.db.DB; @@ -67,7 +67,7 @@ public class LocalStoragePoolListener implements Listener { @Override @DB - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupStorageCommand)) { return; } diff --git a/server/src/com/cloud/storage/download/DownloadAbandonedState.java b/server/src/com/cloud/storage/download/DownloadAbandonedState.java index 200683c4c33..ef053ce2737 100644 --- a/server/src/com/cloud/storage/download/DownloadAbandonedState.java +++ b/server/src/com/cloud/storage/download/DownloadAbandonedState.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.storage.download; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -34,7 +35,8 @@ public class DownloadAbandonedState extends DownloadInactiveState { public void onEntry(String prevState, DownloadEvent event, Object evtObj) { super.onEntry(prevState, event, evtObj); if (!prevState.equalsIgnoreCase(getName())){ - getDownloadListener().updateDatabase(Status.ABANDONED, "Download canceled"); + DownloadAnswer answer = new DownloadAnswer("Download canceled", Status.ABANDONED); + getDownloadListener().callback(answer); getDownloadListener().cancelStatusTask(); getDownloadListener().cancelTimeoutTask(); getDownloadListener().sendCommand(RequestType.ABORT); diff --git a/server/src/com/cloud/storage/download/DownloadActiveState.java b/server/src/com/cloud/storage/download/DownloadActiveState.java index f2cd5af4c71..09d103ef27c 100644 --- a/server/src/com/cloud/storage/download/DownloadActiveState.java +++ b/server/src/com/cloud/storage/download/DownloadActiveState.java @@ -64,7 +64,7 @@ public abstract class DownloadActiveState extends DownloadState { } if (event==DownloadEvent.DOWNLOAD_ANSWER) { - getDownloadListener().updateDatabase((DownloadAnswer)evtObj); + getDownloadListener().callback((DownloadAnswer)evtObj); getDownloadListener().setLastUpdated(); } diff --git a/server/src/com/cloud/storage/download/DownloadErrorState.java b/server/src/com/cloud/storage/download/DownloadErrorState.java index 0fdfd523ba5..e5c88205309 100644 --- a/server/src/com/cloud/storage/download/DownloadErrorState.java +++ b/server/src/com/cloud/storage/download/DownloadErrorState.java @@ -76,10 +76,12 @@ public class DownloadErrorState extends DownloadInactiveState { getDownloadListener().logDisconnect(); getDownloadListener().cancelStatusTask(); getDownloadListener().cancelTimeoutTask(); - getDownloadListener().updateDatabase(Status.DOWNLOAD_ERROR, "Storage agent or storage VM disconnected"); + DownloadAnswer answer = new DownloadAnswer("Storage agent or storage VM disconnected", Status.DOWNLOAD_ERROR); + getDownloadListener().callback(answer); getDownloadListener().log("Entering download error state because the storage host disconnected", Level.WARN); } else if (event==DownloadEvent.TIMEOUT_CHECK){ - getDownloadListener().updateDatabase(Status.DOWNLOAD_ERROR, "Timeout waiting for response from storage host"); + DownloadAnswer answer = new DownloadAnswer("Timeout waiting for response from storage host", Status.DOWNLOAD_ERROR); + getDownloadListener().callback(answer); getDownloadListener().log("Entering download error state: timeout waiting for response from storage host", Level.WARN); } getDownloadListener().setDownloadInactive(Status.DOWNLOAD_ERROR); diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 3eb223325cb..e54e879110e 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -25,17 +25,15 @@ import java.util.TimerTask; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -47,35 +45,19 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; -import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; -import com.cloud.alert.AlertManager; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; +import com.cloud.host.Host; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ResourceManager; -import com.cloud.storage.Storage; -import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadState.DownloadEvent; -import com.cloud.user.AccountManager; -import com.cloud.user.ResourceLimitService; -import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; /** @@ -125,25 +107,11 @@ public class DownloadListener implements Listener { public static final String DOWNLOAD_IN_PROGRESS=Status.DOWNLOAD_IN_PROGRESS.toString(); public static final String DOWNLOAD_ABANDONED=Status.ABANDONED.toString(); + private EndPoint _ssAgent; - private HostVO _sserver; - private HostVO _ssAgent; + private DataObject object; - private VMTemplateVO _template; - private VolumeVO _volume; private boolean _downloadActive = true; - - private VolumeHostDao _volumeHostDao; - private VolumeDataStoreDao _volumeStoreDao; - private VolumeDao _volumeDao; - private StorageManager _storageMgr; - private VMTemplateHostDao _vmTemplateHostDao; - private TemplateDataStoreDao _vmTemplateStoreDao; - private VMTemplateDao _vmTemplateDao; - private ResourceLimitService _resourceLimitMgr; - private AccountManager _accountMgr; - private AlertManager _alertMgr; - private final DownloadMonitorImpl _downloadMonitor; private DownloadState _currState; @@ -158,13 +126,7 @@ public class DownloadListener implements Listener { private String _jobId; private final Map _stateMap = new HashMap(); - private Long _templateHostId; - private Long _volumeHostId; - - private DataStore _sstore; - private Long _templateStoreId; - private Long _volumeStoreId; - private AsyncCompletionCallback _callback; + private AsyncCompletionCallback _callback; @Inject private ResourceManager _resourceMgr; @@ -175,71 +137,25 @@ public class DownloadListener implements Listener { @Inject private VolumeService _volumeSrv; - public DownloadListener(HostVO ssAgent, HostVO host, VMTemplateVO template, Timer _timer, VMTemplateHostDao dao, Long templHostId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr) { - this._ssAgent = ssAgent; - this._sserver = host; - this._template = template; - this._vmTemplateHostDao = dao; - this._downloadMonitor = downloadMonitor; - this._cmd = cmd; - this._templateHostId = templHostId; - initStateMachine(); - this._currState=getState(Status.NOT_DOWNLOADED.toString()); - this._timer = _timer; - this._timeoutTask = new TimeoutTask(this); - this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); - this._vmTemplateDao = templateDao; - this._resourceLimitMgr = _resourceLimitMgr; - this._accountMgr = _accountMgr; - this._alertMgr = _alertMgr; - updateDatabase(Status.NOT_DOWNLOADED, ""); - } - // TODO: this constructor should be the one used for template only, remove other template constructor later - public DownloadListener(HostVO ssAgent, DataStore store, VMTemplateVO template, Timer _timer, TemplateDataStoreDao dao, Long templStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VMTemplateDao templateDao, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback callback) { + public DownloadListener(EndPoint ssAgent, DataStore store, DataObject object, Timer _timer, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, AsyncCompletionCallback callback) { this._ssAgent = ssAgent; - this._sstore = store; - this._template = template; - this._vmTemplateStoreDao = dao; + this.object = object; this._downloadMonitor = downloadMonitor; this._cmd = cmd; - this._templateStoreId = templStoreId; initStateMachine(); this._currState=getState(Status.NOT_DOWNLOADED.toString()); this._timer = _timer; this._timeoutTask = new TimeoutTask(this); this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); - this._vmTemplateDao = templateDao; - this._resourceLimitMgr = _resourceLimitMgr; - this._accountMgr = _accountMgr; - this._alertMgr = _alertMgr; this._callback = callback; - updateDatabase(Status.NOT_DOWNLOADED, ""); + DownloadAnswer answer = new DownloadAnswer("", Status.NOT_DOWNLOADED); + callback(answer); + } + + public AsyncCompletionCallback getCallback() { + return this._callback; } - - - public DownloadListener(HostVO ssAgent, DataStore store, VolumeVO volume, Timer _timer, VolumeDataStoreDao dao, Long volStoreId, DownloadMonitorImpl downloadMonitor, DownloadCommand cmd, VolumeDao volumeDao, StorageManager storageMgr, ResourceLimitService _resourceLimitMgr, AlertManager _alertMgr, AccountManager _accountMgr, AsyncCompletionCallback callback) { - this._ssAgent = ssAgent; - this._sstore = store; - this._volume = volume; - this._volumeStoreDao = dao; - this._downloadMonitor = downloadMonitor; - this._cmd = cmd; - this._volumeStoreId = volStoreId; - initStateMachine(); - this._currState=getState(Status.NOT_DOWNLOADED.toString()); - this._timer = _timer; - this._timeoutTask = new TimeoutTask(this); - this._timer.schedule(_timeoutTask, 3*STATUS_POLL_INTERVAL); - this._volumeDao = volumeDao; - this._storageMgr = storageMgr; - this._resourceLimitMgr = _resourceLimitMgr; - this._accountMgr = _accountMgr; - this._alertMgr = _alertMgr; - this._callback = callback; - updateDatabase(Status.NOT_DOWNLOADED, ""); - } - public void setCurrState(VMTemplateHostVO.Status currState) { this._currState = getState(currState.toString()); @@ -264,7 +180,7 @@ public class DownloadListener implements Listener { } try { DownloadProgressCommand dcmd = new DownloadProgressCommand(getCommand(), getJobId(), reqType); - if (_template == null){ + if (this.object.getType() == DataObjectType.VOLUME) { dcmd.setResourceType(ResourceType.VOLUME); } _downloadMonitor.send(_ssAgent.getId(), dcmd, this); @@ -285,59 +201,12 @@ public class DownloadListener implements Listener { } public void logDisconnect() { - if (_template != null){ - s_logger.warn("Unable to monitor download progress of " + _template.getName() + " at host " + _sserver.getName()); - }else { - s_logger.warn("Unable to monitor download progress of " + _volume.getName() + " at host " + _sserver.getName()); - } - } - - public synchronized void updateDatabase(Status state, String errorString) { - if (_template != null){ - VMTemplateHostVO vo = _vmTemplateHostDao.createForUpdate(); - vo.setDownloadState(state); - vo.setLastUpdated(new Date()); - vo.setErrorString(errorString); - _vmTemplateHostDao.update(getTemplateHostId(), vo); - }else { - VolumeHostVO vo = _volumeHostDao.createForUpdate(); - vo.setDownloadState(state); - vo.setLastUpdated(new Date()); - vo.setErrorString(errorString); - _volumeHostDao.update(getVolumeHostId(), vo); - } + s_logger.warn("Unable to monitor download progress of " + this.object.getType() + ": " + + this.object.getId() + " at host " + _ssAgent.getId()); } public void log(String message, Level level) { - if (_template != null){ - s_logger.log(level, message + ", template=" + _template.getName() + " at host " + _sserver.getName()); - }else { - s_logger.log(level, message + ", volume=" + _volume.getName() + " at host " + _sserver.getName()); - } - } - - private Long getTemplateHostId() { - if (_templateHostId == null){ - VMTemplateHostVO templHost = _vmTemplateHostDao.findByHostTemplate(_sserver.getId(), _template.getId()); - _templateHostId = templHost.getId(); - } - return _templateHostId; - } - - private Long getTemplateStoreId() { - if (_templateStoreId == null){ - TemplateDataStoreVO templStore = _vmTemplateStoreDao.findByStoreTemplate(_sstore.getId(), _template.getId()); - _templateStoreId = templStore.getId(); - } - return _templateStoreId; - } - - private Long getVolumeHostId() { - if (_volumeHostId == null){ - VolumeHostVO volHost = _volumeHostDao.findByHostVolume(_sserver.getId(), _volume.getId()); - _volumeHostId = volHost.getId(); - } - return _volumeHostId; + s_logger.log(level, message + ", " + this.object.getType() + ": " + this.object.getId() + " at host " + _ssAgent.getId()); } public DownloadListener(DownloadMonitorImpl monitor) { @@ -388,112 +257,10 @@ public class DownloadListener implements Listener { } } - public synchronized void updateDatabase(DownloadAnswer answer) { - if (_template != null){ - TemplateDataStoreVO updateBuilder = _vmTemplateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - - // only invoke callback when Download is completed or errored so that callback will update template_store_ref state column - Status dndStatus = answer.getDownloadStatus(); - // if (dndStatus == Status.DOWNLOAD_ERROR || dndStatus == Status.DOWNLOADED ){ - if ( _callback != null ){ - if (dndStatus == Status.DOWNLOAD_ERROR){ - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSucess(false); - result.setResult("Download template failed"); - _callback.complete(result); - } else if (dndStatus == Status.DOWNLOADED){ - CreateCmdResult result = new CreateCmdResult(null, null); - _callback.complete(result); - } - } - else{ - // no callback specified, just update state here - if (dndStatus == Status.DOWNLOAD_ERROR){ - updateBuilder.setState(ObjectInDataStoreStateMachine.State.Failed); - } else if (dndStatus == Status.DOWNLOAD_IN_PROGRESS){ - updateBuilder.setState(ObjectInDataStoreStateMachine.State.Creating2); - } else if (dndStatus == Status.DOWNLOADED){ - updateBuilder.setState(ObjectInDataStoreStateMachine.State.Ready); - } - } - // } - _vmTemplateStoreDao.update(getTemplateStoreId(), updateBuilder); - - if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - _vmTemplateDao.update(_template.getId(), templateDaoBuilder); - } - - if (answer.getTemplateSize() > 0) { - //long hostId = vmTemplateHostDao.findByTemplateId(template.getId()).getHostId(); - long accountId = _template.getAccountId(); - try { - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - answer.getTemplateSize() - UriUtils.getRemoteSize(_template.getUrl())); - } catch (ResourceAllocationException e) { - s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _sserver.getDataCenterId(), - null, e.getMessage(), e.getMessage()); - } finally { - _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - } - - } else { - VolumeHostVO updateBuilder = _volumeHostDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - - _volumeHostDao.update(getVolumeHostId(), updateBuilder); - - // Update volume size in Volume table. - VolumeVO updateVolume = _volumeDao.createForUpdate(); - updateVolume.setSize(answer.getTemplateSize()); - _volumeDao.update(_volume.getId(), updateVolume); - - if (answer.getTemplateSize() > 0) { - try { - String url = _volumeHostDao.findByVolumeId(_volume.getId()).getDownloadUrl(); - _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(_volume.getAccountId()), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - answer.getTemplateSize() - UriUtils.getRemoteSize(url)); - } catch (ResourceAllocationException e) { - s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, _volume.getDataCenterId(), - _volume.getPodId(), e.getMessage(), e.getMessage()); - } finally { - _resourceLimitMgr.recalculateResourceCount(_volume.getAccountId(), _volume.getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - } - - /*if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = _vmTemplateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - _vmTemplateDao.update(template.getId(), templateDaoBuilder); - }*/ - } - } - + public void callback(DownloadAnswer answer) { + this._callback.complete(answer); + } + @Override public boolean processCommands(long agentId, long seq, Command[] req) { return false; @@ -511,7 +278,7 @@ public class DownloadListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { List hypers = _resourceMgr.listAvailHypervisorInZone(agent.getId(), agent.getDataCenterId()); HypervisorType hostHyper = agent.getHypervisorType(); @@ -601,11 +368,6 @@ public class DownloadListener implements Listener { public void setDownloadInactive(Status reason) { _downloadActive=false; - if (_template != null){ - _downloadMonitor.handleDownloadEvent(_sserver, _template, reason); - }else { - _downloadMonitor.handleDownloadEvent(_sserver, _volume, reason); - } } public void cancelTimeoutTask() { diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index efbdbe2c5c6..7bc210f2c83 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -16,15 +16,15 @@ // under the License. package com.cloud.storage.download; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.exception.StorageUnavailableException; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeVO; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.component.Manager; /** @@ -34,19 +34,15 @@ import com.cloud.utils.component.Manager; public interface DownloadMonitor extends Manager{ // when ssvm is not available yet - public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); - public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); + public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback); - public void cancelAllDownloads(Long templateId); + //public void cancelAllDownloads(Long templateId); - public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store) - throws StorageUnavailableException; + //public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store) + // throws StorageUnavailableException; - //void addSystemVMTemplatesToHost(HostVO host, Map templateInfos); - - //public boolean downloadVolumeToStorage(VolumeVO volume, Long zoneId, String url, String checkSum, ImageFormat format); - - public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); + public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index c7b360aa77a..b72c2021316 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -27,14 +27,14 @@ import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; -import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; @@ -45,55 +45,35 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.Command; - +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; - import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; - -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; -import com.cloud.event.dao.UsageEventDao; import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.resource.ResourceManager; import com.cloud.storage.Storage.ImageFormat; - import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Volume; import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.storage.dao.SwiftDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VMTemplateSwiftDao; -import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; - import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; import com.cloud.template.TemplateManager; -import com.cloud.user.Account; +import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.component.ManagerBase; @@ -101,37 +81,17 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.SecondaryStorageVm; -import com.cloud.vm.SecondaryStorageVmVO; import com.cloud.vm.UserVmManager; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - @Component @Local(value = { DownloadMonitor.class }) public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor { static final Logger s_logger = Logger.getLogger(DownloadMonitorImpl.class); - @Inject - VMTemplateHostDao _vmTemplateHostDao; @Inject TemplateDataStoreDao _vmTemplateStoreDao; @Inject - VMTemplateZoneDao _vmTemplateZoneDao; - @Inject - VMTemplatePoolDao _vmTemplatePoolDao; - @Inject - VMTemplateSwiftDao _vmTemplateSwiftlDao; - @Inject - StoragePoolHostDao _poolHostDao; - @Inject - SecondaryStorageVmDao _secStorageVmDao; - @Inject ImageStoreDao _imageStoreDao; @Inject VolumeDao _volumeDao; @@ -147,9 +107,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor SecondaryStorageVmManager _ssvmMgr; @Inject StorageManager _storageMgr; - - @Inject - private final DataCenterDao _dcDao = null; @Inject VMTemplateDao _templateDao = null; @Inject @@ -164,17 +121,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject TemplateManager templateMgr; - @Inject - private UsageEventDao _usageEventDao; - - @Inject - private ClusterDao _clusterDao; - @Inject - private HostDao _hostDao; - @Inject - private ResourceManager _resourceMgr; - @Inject - private SwiftDao _swiftDao; @Inject protected ResourceLimitService _resourceLimitMgr; @Inject @@ -254,6 +200,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } // TODO: consider using dataMotionStrategy later + /* @Override public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore destStore) throws StorageUnavailableException { @@ -363,15 +310,15 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId()); HypervisorType hyperType = tmplt.getHypervisorType(); - /*No secondary storage vm yet*/ + if (hyperType != null && hyperType == HypervisorType.KVM) { //return "file://" + sourceServer.getParent() + "/" + srcTmpltStore.getInstallPath(); return "file://" + "/" + srcTmpltStore.getInstallPath(); } return null; - } + }*/ - private void initiateTemplateDownload(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + private void initiateTemplateDownload(DataObject template, DataStore store, AsyncCompletionCallback callback) { boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; @@ -380,7 +327,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor // This method can be invoked other places, for example, // handleTemplateSync, in that case, vmTemplateStore may be null vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, - VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); + VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUri()); _vmTemplateStoreDao.persist(vmTemplateStore); } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { downloadJobExists = true; @@ -390,7 +337,8 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor String secUrl = store.getUri(); if (vmTemplateStore != null) { start(); - DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); + VirtualMachineTemplate tmpl = this._templateDao.findById(template.getId()); + DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, tmpl, maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); @@ -398,13 +346,13 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (vmTemplateStore.isCopy()) { dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - if (ssAhost == null) { + EndPoint ep = _epSelector.select(template); + if (ep == null) { s_logger.warn("There is no secondary storage VM for downloading template to image store " + store.getName()); return; } - DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, - _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd, + callback); if (downloadJobExists) { // due to handling existing download job issues, we still keep // downloadState in template_store_ref to avoid big change in @@ -422,9 +370,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } try { - send(ssAhost.getId(), dcmd, dl); - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of template " + template.getUniqueName() + " to " + store.getName(), e); + ep.sendMessageAsyncWithListener(dcmd, dl); + } catch (Exception e) { + s_logger.warn("Unable to start /resume download of template " + template.getId() + " to " + store.getName(), e); dl.setDisconnected(); dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } @@ -433,7 +381,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Override - public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; @@ -495,18 +443,18 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } @Override - public void downloadTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { + public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); if (isTemplateUpdateable(templateId, store.getId())) { - if (template != null && template.getUrl() != null) { + if (template != null && template.getUri() != null) { initiateTemplateDownload(template, store, callback); } } } @Override - public void downloadVolumeToStorage(VolumeVO volume, DataStore store, String url, String checkSum, ImageFormat format, - AsyncCompletionCallback callback) { + public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, + AsyncCompletionCallback callback) { boolean downloadJobExists = false; VolumeDataStoreVO volumeHost = null; @@ -523,20 +471,20 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor String secUrl = store.getUri(); if (volumeHost != null) { start(); - DownloadCommand dcmd = new DownloadCommand(secUrl, volume, maxVolumeSizeInBytes, checkSum, url, format); + Volume vol = this._volumeDao.findById(volume.getId()); + DownloadCommand dcmd = new DownloadCommand(secUrl, vol, maxVolumeSizeInBytes, checkSum, url, format); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); dcmd.setResourceType(ResourceType.VOLUME); } - HostVO ssAhost = _ssvmMgr.pickSsvmHost(store); - if (ssAhost == null) { + EndPoint ep = this._epSelector.select(volume); + if (ep == null) { s_logger.warn("There is no secondary storage VM for image store " + store.getName()); return; } - DownloadListener dl = new DownloadListener(ssAhost, store, volume, _timer, _volumeStoreDao, volumeHost.getId(), this, dcmd, _volumeDao, - _storageMgr, _resourceLimitMgr, _alertMgr, _accountMgr, callback); + DownloadListener dl = new DownloadListener(ep, store, volume, _timer, this, dcmd, callback); if (downloadJobExists) { dl.setCurrState(volumeHost.getDownloadState()); @@ -550,59 +498,26 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } try { - send(ssAhost.getId(), dcmd, dl); - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume download of volume " + volume.getName() + " to " + store.getName(), e); + ep.sendMessageAsyncWithListener(dcmd, dl); + } catch (Exception e) { + s_logger.warn("Unable to start /resume download of volume " + volume.getId() + " to " + store.getName(), e); dl.setDisconnected(); dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); } } } - @DB - public void handleDownloadEvent(HostVO host, VMTemplateVO template, Status dnldStatus) { - if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { - VMTemplateHostVO vmTemplateHost = new VMTemplateHostVO(host.getId(), template.getId()); - synchronized (_listenerMap) { - _listenerMap.remove(vmTemplateHost); - } - } - - VMTemplateHostVO vmTemplateHost = _vmTemplateHostDao.findByHostTemplate(host.getId(), template.getId()); - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - if (dnldStatus == Status.DOWNLOADED) { - long size = -1; - if (vmTemplateHost != null) { - size = vmTemplateHost.getPhysicalSize(); - template.setSize(size); - this._templateDao.update(template.getId(), template); - } else { - s_logger.warn("Failed to get size for template" + template.getName()); - } - String eventType = EventTypes.EVENT_TEMPLATE_CREATE; - if ((template.getFormat()).equals(ImageFormat.ISO)) { - eventType = EventTypes.EVENT_ISO_CREATE; - } - if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), host.getDataCenterId(), template.getId(), template.getName(), - null, template.getSourceTemplateId(), size, template.getClass().getName(), template.getUuid()); - } - } - txn.commit(); - } @DB - public void handleDownloadEvent(HostVO host, VolumeVO volume, Status dnldStatus) { - if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { + public void handleDownloadEvent(HostVO host, DataObject object, Status dnldStatus) { + /* if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId()); synchronized (_listenerVolumeMap) { _listenerVolumeMap.remove(volumeHost); } - } + }*/ + /* VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId()); Transaction txn = Transaction.currentTxn(); @@ -631,6 +546,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); } txn.commit(); + */ } /* @@ -657,7 +573,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } */ - @Override + /*@Override public void cancelAllDownloads(Long templateId) { List downloadsInProgress = _vmTemplateHostDao.listByTemplateStates(templateId, VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.NOT_DOWNLOADED); @@ -673,7 +589,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } } } - } + }*/ /* private void checksumSync(long hostId){ diff --git a/server/src/com/cloud/storage/download/DownloadState.java b/server/src/com/cloud/storage/download/DownloadState.java index 471ab6124f7..9d404f02e37 100644 --- a/server/src/com/cloud/storage/download/DownloadState.java +++ b/server/src/com/cloud/storage/download/DownloadState.java @@ -62,7 +62,7 @@ public abstract class DownloadState { getDownloadListener().log("onEntry, event type=" + event + ", curr state=" + getName(), Level.TRACE); } if (event==DownloadEvent.DOWNLOAD_ANSWER) { - getDownloadListener().updateDatabase((DownloadAnswer)evtObj); + getDownloadListener().callback((DownloadAnswer)evtObj); } } diff --git a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java index e035fd7c26f..8c894402c17 100755 --- a/server/src/com/cloud/storage/listener/StoragePoolMonitor.java +++ b/server/src/com/cloud/storage/listener/StoragePoolMonitor.java @@ -32,7 +32,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.exception.ConnectionException; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.OCFS2Manager; @@ -71,7 +71,7 @@ public class StoragePoolMonitor implements Listener { } @Override - public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (cmd instanceof StartupRoutingCommand) { StartupRoutingCommand scCmd = (StartupRoutingCommand)cmd; if (scCmd.getHypervisorType() == HypervisorType.XenServer || scCmd.getHypervisorType() == HypervisorType.KVM || diff --git a/server/src/com/cloud/storage/listener/StorageSyncListener.java b/server/src/com/cloud/storage/listener/StorageSyncListener.java index d9282a35ad7..5b7c7f75980 100755 --- a/server/src/com/cloud/storage/listener/StorageSyncListener.java +++ b/server/src/com/cloud/storage/listener/StorageSyncListener.java @@ -24,7 +24,7 @@ import com.cloud.agent.api.AgentControlCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; public class StorageSyncListener implements Listener { @@ -51,7 +51,7 @@ public class StorageSyncListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { } @Override diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java index 6635b3cf317..d524f29008d 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageListener.java @@ -27,7 +27,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.StartupStorageCommand; -import com.cloud.host.HostVO; +import com.cloud.host.Host; import com.cloud.host.Status; import com.cloud.storage.Storage; @@ -68,7 +68,7 @@ public class SecondaryStorageListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { if ((cmd instanceof StartupStorageCommand) ) { StartupStorageCommand scmd = (StartupStorageCommand)cmd; if (scmd.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE ) { diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index ee13cf9b0d8..891610f46f6 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -47,6 +47,7 @@ import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobResult; import com.cloud.exception.AgentUnavailableException; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.storage.Storage; import com.cloud.storage.Upload.Status; @@ -248,7 +249,7 @@ public class UploadListener implements Listener { } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) { if (!(cmd instanceof StartupStorageCommand)) { return; } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 34efdcb40ca..cb0bee9cc76 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -35,16 +35,21 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DeleteTemplateCommand; +import com.cloud.alert.AlertManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; import com.cloud.event.EventTypes; @@ -80,6 +85,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te @Inject TemplateService imageService; @Inject TemplateDataFactory imageFactory; @Inject TemplateManager templateMgr; + @Inject AlertManager alertMgr; @Override public String getName() { @@ -181,23 +187,37 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te throw new CloudRuntimeException("Unable to find image store to download template "+ profile.getTemplate()); } for (DataStore imageStore : imageStores) { - AsyncCallFuture future = this.imageService - .createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore); - try { - future.get(); - } catch (InterruptedException e) { - s_logger.debug("create template Failed", e); - throw new CloudRuntimeException("create template Failed", e); - } catch (ExecutionException e) { - s_logger.debug("create template Failed", e); - throw new CloudRuntimeException("create template Failed", e); - } + TemplateInfo tmpl = this.imageFactory.getTemplate(template.getId(), imageStore); + CreateTemplateContext context = new CreateTemplateContext(null, tmpl); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(this.createTemplateAsyncCallBack(null, null)); + caller.setContext(context); + this.imageService + .createTemplateAsync(tmpl, imageStore, caller); } _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); - _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage, - UriUtils.getRemoteSize(profile.getUrl())); + return template; } + + private class CreateTemplateContext extends AsyncRpcConext { + final TemplateInfo template; + public CreateTemplateContext(AsyncCompletionCallback callback, TemplateInfo template) { + super(callback); + this.template = template; + } + } + + protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher callback, CreateTemplateContext context) { + TemplateInfo template = context.template; + VMTemplateVO tmplt = this._tmpltDao.findById(template.getId()); + long accountId = tmplt.getAccountId(); + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, + template.getSize()); + + return null; + } @Override @DB public boolean delete(TemplateProfile profile) { diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index af2271660fa..ea20dd57773 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -2285,7 +2285,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } @Override - public void processConnect(HostVO agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + public void processConnect(Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand)) { return; } From f3ee8fbd7df7da443a7e0c68f3870b1213fb9c0a Mon Sep 17 00:00:00 2001 From: Edison Su Date: Sun, 21 Apr 2013 23:15:50 -0700 Subject: [PATCH 043/303] clean up createasync --- .../CloudStackPrimaryDataStoreDriverImpl.java | 109 +++--------------- 1 file changed, 14 insertions(+), 95 deletions(-) diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 2a9217de6c4..ea4c5615423 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -49,18 +49,12 @@ import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.StorageFilerTO; 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.ResizeVolumePayload; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.SnapshotVO; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.DiskOfferingDao; @@ -68,8 +62,6 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.template.TemplateManager; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.dao.VMInstanceDao; @@ -79,7 +71,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Inject DiskOfferingDao diskOfferingDao; @Inject VMTemplateDao templateDao; @Inject VolumeDao volumeDao; - @Inject TemplateManager templateMgr; @Inject HostDao hostDao; @Inject StorageManager storageMgr; @Inject VolumeManager volumeMgr; @@ -127,11 +118,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri DiskProfile diskProfile = new DiskProfile(volume, offering, null); - VMTemplateVO template = null; - if (volume.getTemplateId() != null) { - template = templateDao.findById(volume.getTemplateId()); - } - StoragePool pool = (StoragePool)volume.getDataStore(); VolumeVO vol = volumeDao.findById(volume.getId()); if (pool != null) { @@ -140,89 +126,22 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } vol.setPoolId(pool.getId()); - CreateCommand cmd = null; - VMTemplateStoragePoolVO tmpltStoredOn = null; + CreateCommand cmd = new CreateCommand(diskProfile, new StorageFilerTO( + pool)); - for (int i = 0; i < 2; i++) { - if (template != null - && template.getFormat() != Storage.ImageFormat.ISO) { - if (pool.getPoolType() == StoragePoolType.CLVM) { - // prepareISOForCreate does what we need, which is to - // tell us where the template is - VMTemplateHostVO tmpltHostOn = templateMgr - .prepareISOForCreate(template, pool); - if (tmpltHostOn == null) { - s_logger.debug("cannot find template " - + template.getId() + " " - + template.getName()); - throw new CloudRuntimeException("cannot find template" - + template.getId() - + template.getName()); - } - HostVO secondaryStorageHost = hostDao - .findById(tmpltHostOn.getHostId()); - String tmpltHostUrl = secondaryStorageHost - .getStorageUrl(); - String fullTmpltUrl = tmpltHostUrl + "/" - + tmpltHostOn.getInstallPath(); - cmd = new CreateCommand(diskProfile, fullTmpltUrl, - new StorageFilerTO(pool)); - } else { - tmpltStoredOn = templateMgr.prepareTemplateForCreate( - template, pool); - if (tmpltStoredOn == null) { - s_logger.debug("Cannot use this pool " + pool - + " because we can't propagate template " - + template); - throw new CloudRuntimeException("Cannot use this pool " + pool - + " because we can't propagate template " - + template); - } - cmd = new CreateCommand(diskProfile, - tmpltStoredOn.getLocalDownloadPath(), - new StorageFilerTO(pool)); - } - } else { - if (template != null - && Storage.ImageFormat.ISO == template.getFormat()) { - VMTemplateHostVO tmpltHostOn = templateMgr - .prepareISOForCreate(template, pool); - if (tmpltHostOn == null) { - throw new CloudRuntimeException( - "Did not find ISO in secondry storage in zone " - + pool.getDataCenterId()); - } - } - cmd = new CreateCommand(diskProfile, new StorageFilerTO( - pool)); - } + Answer answer = storageMgr.sendToPool(pool, null, cmd); + if (answer.getResult()) { + 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.volumeDao.update(vol.getId(), vol); + return true; + } - Answer answer = storageMgr.sendToPool(pool, null, cmd); - if (answer.getResult()) { - 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.volumeDao.update(vol.getId(), vol); - return true; - } else { - if (tmpltStoredOn != null - && (answer instanceof CreateAnswer) - && ((CreateAnswer) answer) - .templateReloadRequested()) { - if (!templateMgr - .resetTemplateDownloadStateOnPool(tmpltStoredOn - .getId())) { - break; // break out of template-redeploy retry loop - } - } else { - break; - } - } - } } if (s_logger.isDebugEnabled()) { From 0a6e3869970e6ee175f269c3788551e61e328612 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 22 Apr 2013 11:18:48 -0700 Subject: [PATCH 044/303] fix callback installation --- .../datastore/driver/CloudStackImageStoreDriverImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 0c078b1e316..049a0364e8e 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -173,7 +173,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - caller.setCallback(callback); + caller.setCallback(this.createAsyncCallback(null, null)); if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; From ffdf567b5843cc93ccb5c4e35ce765834da17099 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 22 Apr 2013 13:19:04 -0700 Subject: [PATCH 045/303] Add implemention to pick EndPoint for secondary storage --- .../api/storage/TemplateService.java | 1 - .../endpoint/DefaultEndPointSelector.java | 50 +++++++++++++++---- .../vmware/manager/VmwareManagerImpl.java | 2 +- .../CloudStackImageStoreDriverImpl.java | 18 +++---- 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index f04b14df050..dd017a11327 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -18,7 +18,6 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index bda2995952b..37ebccde8c8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -22,6 +22,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.inject.Inject; @@ -37,6 +38,7 @@ import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; @@ -71,7 +73,7 @@ public class DefaultEndPointSelector implements EndPointSelector { return false; } } - + protected boolean moveBetweenCacheAndImage(DataStore srcStore, DataStore destStore) { DataStoreRole srcRole = srcStore.getRole(); DataStoreRole destRole = destStore.getRole(); @@ -162,7 +164,7 @@ public class DefaultEndPointSelector implements EndPointSelector { } else if (moveBetweenCacheAndImage(srcStore, destStore)) { EndPoint ep = findEndPointForImageMove(srcStore, destStore); if (ep == null) { - //if there is no ssvm agent running, use mgt server + //if there is no ssvm agent running, use mgt server ep = new LocalHostEndpoint(); } return ep; @@ -170,11 +172,41 @@ public class DefaultEndPointSelector implements EndPointSelector { // TODO Auto-generated method stub return null; } - + protected EndPoint findEndpointForPrimaryStorage(DataStore store) { return findEndPointInScope(store.getScope(), findOneHostOnPrimaryStorage); } - + + + protected EndPoint findEndpointForImageStorage(DataStore store) { + Long dcId = null; + Scope storeScope = store.getScope(); + if (storeScope.getScopeType() == ScopeType.ZONE) { + dcId = storeScope.getScopeId(); + } + // find ssvm that can be used to download data to store. For zone-wide + // image store, use SSVM for that zone. For region-wide store, + // we can arbitrarily pick one ssvm to do that task + List ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId); + if (ssAHosts == null || ssAHosts.isEmpty()) { + return new LocalHostEndpoint(); // use local host as endpoint in + // case of no ssvm existing + } + Collections.shuffle(ssAHosts); + HostVO host = ssAHosts.get(0); + return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress()); + } + + private List listUpAndConnectingSecondaryStorageVmHost(Long dcId) { + SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); + if (dcId != null) { + sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); + } + sc.addAnd(sc.getEntity().getStatus(), Op.IN, com.cloud.host.Status.Up, com.cloud.host.Status.Connecting); + sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.SecondaryStorageVM); + return sc.list(); + } + @Override public EndPoint select(DataObject object) { DataStore store = object.getDataStore(); @@ -182,14 +214,14 @@ public class DefaultEndPointSelector implements EndPointSelector { return findEndpointForPrimaryStorage(store); } else if (store.getRole() == DataStoreRole.Image) { //in case there is no ssvm, directly send down command hypervisor host - //TODO: add code to handle in case ssvm is there - return findEndpointForPrimaryStorage(store); + // otherwise, send to localhost for bootstrap system vm template download + return findEndpointForImageStorage(store); }else { throw new CloudRuntimeException("not implemented yet"); } - + } - + @Override public List selectAll(DataStore store) { List endPoints = new ArrayList(); @@ -206,7 +238,7 @@ public class DefaultEndPointSelector implements EndPointSelector { endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress())); } - + } else { throw new CloudRuntimeException("shouldn't use it for other scope"); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index ba99da11996..4ae0d17ac67 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -710,7 +710,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw } @DB - private void updateClusterNativeHAState(HostVO host, StartupCommand cmd) { + private void updateClusterNativeHAState(Host host, StartupCommand cmd) { ClusterVO cluster = _clusterDao.findById(host.getClusterId()); if(cluster.getClusterType() == ClusterType.ExternalManaged) { if(cmd instanceof StartupRoutingCommand) { diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 049a0364e8e..46aae5601d3 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -164,17 +164,17 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { super(callback); this.data = data; } - + } @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { createObjectContext context = new createObjectContext(callback, data); - AsyncCallbackDispatcher caller = + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); caller.setCallback(this.createAsyncCallback(null, null)); - + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); @@ -185,8 +185,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); } } - - protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + + protected Void createAsyncCallback(AsyncCallbackDispatcher callback, createObjectContext context) { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; @@ -203,9 +203,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); _templateStoreDao.update(store.getId(), updateBuilder); - + AsyncCompletionCallback caller = context.getParentCallback(); - + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { @@ -219,8 +219,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { templateDaoBuilder.setChecksum(answer.getCheckSum()); templateDao.update(obj.getId(), templateDaoBuilder); } - - + + CreateCmdResult result = new CreateCmdResult(null, null); caller.complete(result); } From 9c584b550058ecf186aef133b308392eaa2a3d0e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 22 Apr 2013 11:57:28 -0700 Subject: [PATCH 046/303] Use EndPoint to send local/remote command, and hide agentMgr message passing. --- .../api/storage/EndPointSelector.java | 3 +++ .../storage/image/TemplateServiceImpl.java | 24 +++++++------------ .../endpoint/DefaultEndPointSelector.java | 7 +++++- .../storage/volume/VolumeServiceImpl.java | 22 +++++++---------- .../CloudStackImageStoreDriverImpl.java | 6 ++++- .../driver/S3ImageStoreDriverImpl.java | 6 ++++- .../driver/SwiftImageStoreDriverImpl.java | 6 ++++- server/src/com/cloud/agent/AgentManager.java | 3 --- .../cloud/agent/manager/AgentManagerImpl.java | 17 +------------ .../com/cloud/storage/StorageManagerImpl.java | 24 ++++++++++--------- .../storage/download/DownloadListener.java | 8 +++---- .../SecondaryStorageManagerImpl.java | 20 ---------------- .../secondary/SecondaryStorageVmManager.java | 1 - .../cloud/template/TemplateManagerImpl.java | 10 +++++--- .../com/cloud/agent/MockAgentManagerImpl.java | 12 ---------- 15 files changed, 67 insertions(+), 102 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java index fe3a1b713ba..d3eb1ecd3f7 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java @@ -29,6 +29,9 @@ public interface EndPointSelector { * @return */ EndPoint select(DataObject object); + + EndPoint select(DataStore store); + /** * @param store * @return diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 0057012945a..2e0da4d3f7a 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -34,6 +34,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; 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.SnapshotInfo; @@ -58,14 +60,12 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; @@ -129,6 +129,8 @@ public class TemplateServiceImpl implements TemplateService { @Inject TemplateDataFactory _templateFactory; @Inject VMTemplatePoolDao _tmpltPoolDao; + @Inject + EndPointSelector _epSelector; class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; @@ -179,7 +181,7 @@ public class TemplateServiceImpl implements TemplateService { } } } - + @Override public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { Set toBeDownloaded = new HashSet(); @@ -377,17 +379,8 @@ public class TemplateServiceImpl implements TemplateService { List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - VMTemplateVO template = _templateDao.findById(tInfo.getId()); - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), store.getUri(), tInfo.getInstallPath(), template.getId(), template.getAccountId()); - try { - _agentMgr.sendToSecStorage(store, dtCommand, null); - } catch (AgentUnavailableException e) { - String err = "Failed to delete " + tInfo.getTemplateName() + " on secondary storage " + storeId + " which isn't in the database"; - s_logger.error(err); - return; - } - - String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId + " since it isn't in the database"; + deleteTemplateAsync(_templateFactory.getTemplate(tInfo.getId(), store)); + String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId; s_logger.info(description); } } @@ -423,7 +416,8 @@ public class TemplateServiceImpl implements TemplateService { private Map listTemplate(DataStore ssStore) { ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getUri()); - Answer answer = _agentMgr.sendToSecStorage(ssStore, cmd); + EndPoint ep = _epSelector.select(ssStore); + Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { ListTemplateAnswer tanswer = (ListTemplateAnswer)answer; return tanswer.getTemplateInfo(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 37ebccde8c8..f48c8e9580c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -210,6 +210,12 @@ public class DefaultEndPointSelector implements EndPointSelector { @Override public EndPoint select(DataObject object) { DataStore store = object.getDataStore(); + return select(store); + } + + + @Override + public EndPoint select(DataStore store) { if (store.getRole() == DataStoreRole.Primary) { return findEndpointForPrimaryStorage(store); } else if (store.getRole() == DataStoreRole.Image) { @@ -219,7 +225,6 @@ public class DefaultEndPointSelector implements EndPointSelector { }else { throw new CloudRuntimeException("not implemented yet"); } - } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 42c61f391a5..99ac50a10dd 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -32,6 +32,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; @@ -53,14 +55,12 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceAllocationException; import com.cloud.storage.StoragePool; @@ -119,6 +119,8 @@ public class VolumeServiceImpl implements VolumeService { VolumeDataStoreDao _volumeStoreDao; @Inject VolumeDao _volumeDao; + @Inject + EndPointSelector _epSelector; public VolumeServiceImpl() { } @@ -659,7 +661,7 @@ public class VolumeServiceImpl implements VolumeService { } else { vo.stateTransit(Volume.Event.OperationSucceeded); }*/ - + _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize()); VolumeApiResult res = new VolumeApiResult(vo); @@ -815,16 +817,9 @@ public class VolumeServiceImpl implements VolumeService { //Delete volumes which are not present on DB. for (Long uniqueName : volumeInfos.keySet()) { TemplateProp vInfo = volumeInfos.get(uniqueName); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getUri(), vInfo.getInstallPath()); - try { - _agentMgr.sendToSecStorage(store, dtCommand, null); - } catch (AgentUnavailableException e) { - String err = "Failed to delete " + vInfo.getTemplateName() + " on image store " + storeId + " which isn't in the database"; - s_logger.error(err); - return; - } + this.expungeVolumeAsync(this.volFactory.getVolume(vInfo.getId(), store)); - String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId + " since it isn't in the database"; + String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId; s_logger.info(description); } @@ -832,7 +827,8 @@ public class VolumeServiceImpl implements VolumeService { private Map listVolume(DataStore store) { ListVolumeCommand cmd = new ListVolumeCommand(store.getUri()); - Answer answer = _agentMgr.sendToSecStorage(store, cmd); + EndPoint ep = _epSelector.select(store); + Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { ListVolumeAnswer tanswer = (ListVolumeAnswer)answer; return tanswer.getTemplateInfo(); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 46aae5601d3..d9113b47eec 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -32,6 +32,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -115,6 +116,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { @Inject private AgentManager _agentMgr; @Inject TemplateDataStoreDao _templateStoreDao; + @Inject EndPointSelector _epSelector; @Override @@ -295,7 +297,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to deleted template at store: " + store.getName()); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 6f5d554dac6..366d2e5250c 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -33,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; @@ -110,6 +111,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { @Inject private AgentManager _agentMgr; @Inject TemplateDataStoreDao _templateStoreDao; + @Inject EndPointSelector _epSelector; @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -243,7 +245,9 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to deleted template at store: " + store.getName()); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 1b9ab2d485a..149361602a4 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -33,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; @@ -110,6 +111,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { @Inject private AgentManager _agentMgr; @Inject TemplateDataStoreDao _templateStoreDao; + @Inject EndPointSelector _epSelector; @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -236,7 +238,9 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to deleted template at store: " + store.getName()); diff --git a/server/src/com/cloud/agent/AgentManager.java b/server/src/com/cloud/agent/AgentManager.java index 8071f28db17..e4d55979191 100755 --- a/server/src/com/cloud/agent/AgentManager.java +++ b/server/src/com/cloud/agent/AgentManager.java @@ -141,9 +141,6 @@ public interface AgentManager extends Manager { Answer sendToSecStorage(HostVO ssHost, Command cmd); - void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException; - - Answer sendToSecStorage(DataStore ssStore, Command cmd); /* working as a lock while agent is being loaded */ public boolean tapLoadingAgents(Long hostId, TapAgentsAction action); diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index c839b82719b..a32e0103d75 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -39,11 +39,8 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.StartupCommandProcessor; @@ -99,7 +96,6 @@ import com.cloud.resource.Discoverer; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.resource.ServerResource; -import com.cloud.server.ManagementService; import com.cloud.storage.StorageManager; import com.cloud.storage.StorageService; import com.cloud.storage.dao.StoragePoolHostDao; @@ -110,7 +106,6 @@ import com.cloud.user.AccountManager; import com.cloud.utils.ActionDelegate; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.db.DB; @@ -381,17 +376,6 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl return attache; } - @Override - public Answer sendToSecStorage(DataStore ssStore, Command cmd) { - HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore); - return easySend(ssAhost.getId(), cmd); - } - - @Override - public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException { - HostVO ssAhost = _ssvmMgr.pickSsvmHost(ssStore); - send(ssAhost.getId(), new Commands(cmd), listener); - } @Override public Answer sendToSecStorage(HostVO ssHost, Command cmd) { @@ -1496,6 +1480,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } } + @Override public void disconnectWithInvestigation(final long hostId, final Status.Event event) { disconnectInternal(hostId, event, true); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 22365752a23..1a59f66f329 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -53,6 +53,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; @@ -328,6 +330,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStoreProviderManager _dataStoreProviderMgr; @Inject private TemplateService _imageSrv; + @Inject EndPointSelector _epSelector; protected List _storagePoolAllocators; public List getStoragePoolAllocators() { @@ -1270,17 +1273,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C .getInstallPath(); if (installPath != null) { - - Answer answer = _agentMgr.sendToSecStorage(store, - new DeleteTemplateCommand( - store.getTO(), - store.getUri(), - destroyedTemplateStoreVO - .getInstallPath(), - destroyedTemplate.getId(), - destroyedTemplate.getAccountId() - - )); + EndPoint ep = _epSelector.select(store); + Command cmd = new DeleteTemplateCommand( + store.getTO(), + store.getUri(), + destroyedTemplateStoreVO + .getInstallPath(), + destroyedTemplate.getId(), + destroyedTemplate.getAccountId() + ); + Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index e54e879110e..aeb5397e8c1 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -152,7 +152,7 @@ public class DownloadListener implements Listener { DownloadAnswer answer = new DownloadAnswer("", Status.NOT_DOWNLOADED); callback(answer); } - + public AsyncCompletionCallback getCallback() { return this._callback; } @@ -201,7 +201,7 @@ public class DownloadListener implements Listener { } public void logDisconnect() { - s_logger.warn("Unable to monitor download progress of " + this.object.getType() + ": " + + s_logger.warn("Unable to monitor download progress of " + this.object.getType() + ": " + this.object.getId() + " at host " + _ssAgent.getId()); } @@ -260,7 +260,7 @@ public class DownloadListener implements Listener { public void callback(DownloadAnswer answer) { this._callback.complete(answer); } - + @Override public boolean processCommands(long agentId, long seq, Command[] req) { return false; @@ -287,7 +287,7 @@ public class DownloadListener implements Listener { } _imageSrv.handleSysTemplateDownload(hostHyper, agent.getDataCenterId()); } - /* This can be removed since + /* This can be removed else if ( cmd instanceof StartupStorageCommand) { StartupStorageCommand storage = (StartupStorageCommand)cmd; if( storage.getResourceType() == Storage.StorageResourceType.SECONDARY_STORAGE || diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 1b50083abc5..7f729c3563d 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -1473,26 +1473,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } - @Override - public HostVO pickSsvmHost(DataStore store) { - if ( store.getRole() == DataStoreRole.Image){ - Long dcId = null; - Scope storeScope = store.getScope(); - if ( storeScope.getScopeType() == ScopeType.ZONE ){ - dcId = storeScope.getScopeId(); - } - // find ssvm that can be used to download data to store. For zone-wide image store, use SSVM for that zone. For region-wide store, - // we can arbitrarily pick one ssvm to do that task - List ssAHosts = listUpAndConnectingSecondaryStorageVmHost(dcId); - if (ssAHosts == null || ssAHosts.isEmpty() ) { - return null; - } - Collections.shuffle(ssAHosts); - return ssAHosts.get(0); - } - return null; - } - @Override public boolean plugNic(Network network, NicTO nic, VirtualMachineTO vm, ReservationContext context, DeployDestination dest) throws ConcurrentOperationException, ResourceUnavailableException, diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java index 8565c38cc08..444727b30fd 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java @@ -55,5 +55,4 @@ public interface SecondaryStorageVmManager extends Manager { public List listAllTypesSecondaryStorageHostsInOneZone(long dataCenterId); public List listUpAndConnectingSecondaryStorageVmHost(Long dcId); public HostVO pickSsvmHost(HostVO ssHost); - public HostVO pickSsvmHost(DataStore store); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index a8d524b7cb5..02669958081 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -59,6 +59,8 @@ import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissions import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -266,6 +268,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject VolumeManager volumeMgr; @Inject VMTemplateHostDao templateHostDao; @Inject ImageStoreDao _imageStoreDao; + @Inject EndPointSelector _epSelector; int _primaryStorageDownloadWait; @@ -807,9 +810,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, public String getChecksum(DataStore store, String templatePath) { String secUrl = store.getUri(); - Answer answer; - answer = _agentMgr.sendToSecStorage(store, new ComputeChecksumCommand( - secUrl, templatePath)); + EndPoint ep = _epSelector.select(store); + ComputeChecksumCommand cmd = new ComputeChecksumCommand( + secUrl, templatePath); + Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { return answer.getDetails(); } diff --git a/server/test/com/cloud/agent/MockAgentManagerImpl.java b/server/test/com/cloud/agent/MockAgentManagerImpl.java index 9e7e163aad9..3ebb5495114 100755 --- a/server/test/com/cloud/agent/MockAgentManagerImpl.java +++ b/server/test/com/cloud/agent/MockAgentManagerImpl.java @@ -142,18 +142,6 @@ public class MockAgentManagerImpl extends ManagerBase implements AgentManager { } - @Override - public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException { - // TODO Auto-generated method stub - - } - - @Override - public Answer sendToSecStorage(DataStore ssStore, Command cmd) { - // TODO Auto-generated method stub - return null; - } - @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub From 5f90aa971a523ac8dc52879bd68a305caa3f29b5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 22 Apr 2013 15:33:43 -0700 Subject: [PATCH 047/303] Implement createTemplateCmd and consolidate several copy calls in TemplateServiceImpl. --- .../storage/image/TemplateServiceImpl.java | 183 +++--------------- .../datastore/ObjectInDataStoreManager.java | 4 +- .../ObjectInDataStoreManagerImpl.java | 52 +++++ 3 files changed, 85 insertions(+), 154 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 2e0da4d3f7a..708bda75347 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -58,7 +58,6 @@ import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; @@ -69,7 +68,6 @@ import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; -import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; @@ -78,7 +76,6 @@ import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; @@ -113,10 +110,6 @@ public class TemplateServiceImpl implements TemplateService { @Inject DownloadMonitor _dlMonitor; @Inject - AgentManager _agentMgr; - @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject DataCenterDao _dcDao = null; @Inject VMTemplateZoneDao _vmTemplateZoneDao; @@ -145,6 +138,12 @@ public class TemplateServiceImpl implements TemplateService { public TemplateObject getTemplate() { return template; } + + public AsyncCallFuture getFuture() { + return future; + } + + } @Override @@ -491,56 +490,43 @@ public class TemplateServiceImpl implements TemplateService { return null; } + private AsyncCallFuture copyAsync(DataObject source, TemplateInfo template, DataStore store){ + AsyncCallFuture future = new AsyncCallFuture(); + DataObject templateOnStore = store.create(template); + templateOnStore.processEvent(Event.CreateOnlyRequested); + + TemplateOpContext context = new TemplateOpContext(null, (TemplateObject) templateOnStore, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null)).setContext(context); + this._motionSrv.copyAsync(source, templateOnStore, caller); + return future; + } + @Override public AsyncCallFuture createTemplateFromSnapshotAsync( SnapshotInfo snapshot, TemplateInfo template, DataStore store) { - // TODO Auto-generated method stub - return null; + return this.copyAsync(snapshot, template, store); } @Override public AsyncCallFuture createTemplateFromVolumeAsync( VolumeInfo volume, TemplateInfo template, DataStore store) { - // TODO Auto-generated method stub - return null; + return this.copyAsync(volume, template, store); } @Override - public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, - DataStore destStore) { - AsyncCallFuture future = new AsyncCallFuture(); - TemplateApiResult res = new TemplateApiResult(srcTemplate); - try{ - // create one entry in template_store_ref - TemplateDataStoreVO destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), srcTemplate.getId()); - if (destTmpltStore == null) { - destTmpltStore = new TemplateDataStoreVO(destStore.getId(), srcTemplate.getId()); - destTmpltStore.setCopy(true); - _vmTemplateStoreDao.persist(destTmpltStore); - } - TemplateInfo destTemplate = this._templateFactory.getTemplate(destTmpltStore.getTemplateId(), destStore); - destTemplate.processEvent(Event.CreateOnlyRequested); - srcTemplate.processEvent(Event.CopyingRequested); + public AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore) { + return this.copyAsync(srcTemplate, srcTemplate, destStore); + } - CopyTemplateContext context = new CopyTemplateContext(null, future, srcTemplate, - destTemplate, - destStore); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null)) - .setContext(context); - this._motionSrv.copyAsync(srcTemplate, destTemplate, caller); - } catch (Exception e) { - s_logger.debug("Failed to copy template", e); - res.setResult(e.toString()); - future.complete(res); - } - return future; + @Override + public AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool) { + return this.copyAsync(srcTemplate, srcTemplate, (DataStore)pool); } protected Void copyTemplateCallBack(AsyncCallbackDispatcher callback, - CopyTemplateContext context) { - TemplateInfo srcTemplate = context.getSrcTemplate(); - TemplateInfo destTemplate = context.getDestTemplate(); + TemplateOpContext context) { + TemplateInfo destTemplate = context.getTemplate(); CopyCommandResult result = callback.getResult(); AsyncCallFuture future = context.getFuture(); TemplateApiResult res = new TemplateApiResult(destTemplate); @@ -548,17 +534,12 @@ public class TemplateServiceImpl implements TemplateService { if (result.isFailed()) { res.setResult(result.getResult()); destTemplate.processEvent(Event.OperationFailed); - srcTemplate.processEvent(Event.OperationFailed); // remove entry from template_store_ref - TemplateDataStoreVO destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(context.getDestStore().getId(), destTemplate.getId()); - _vmTemplateStoreDao.remove(destTmpltStore.getId()); - future.complete(res); - return null; + destTemplate.getDataStore().delete(destTemplate); + } else { + destTemplate.processEvent(Event.OperationSuccessed); } - srcTemplate.processEvent(Event.OperationSuccessed); - destTemplate.processEvent(Event.OperationSuccessed); future.complete(res); - return null; } catch (Exception e) { s_logger.debug("Failed to process copy template callback", e); res.setResult(e.toString()); @@ -568,106 +549,4 @@ public class TemplateServiceImpl implements TemplateService { return null; } - protected Void prepareTemplateCallBack(AsyncCallbackDispatcher callback, - CopyTemplateContext context) { - TemplateInfo srcTemplate = context.getSrcTemplate(); - TemplateInfo destTemplate = context.getDestTemplate(); - CopyCommandResult result = callback.getResult(); - AsyncCallFuture future = context.getFuture(); - TemplateApiResult res = new TemplateApiResult(destTemplate); - try { - if (result.isFailed()) { - res.setResult(result.getResult()); - destTemplate.processEvent(Event.OperationFailed); - srcTemplate.processEvent(Event.OperationFailed); - // remove entry from template_spool_ref - VMTemplateStoragePoolVO destTmpltPool = _tmpltPoolDao.findByPoolTemplate(context.getDestStore().getId(), destTemplate.getId()); - _vmTemplateStoreDao.remove(destTmpltPool.getId()); - future.complete(res); - return null; - } - srcTemplate.processEvent(Event.OperationSuccessed); - // update other information in template_spool_ref through templateObject event processing. - destTemplate.processEvent(Event.OperationSuccessed); - future.complete(res); - return null; - } catch (Exception e) { - s_logger.debug("Failed to process prepare template callback", e); - res.setResult(e.toString()); - future.complete(res); - } - - return null; - } - - @Override - public AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool) { - AsyncCallFuture future = new AsyncCallFuture(); - TemplateApiResult res = new TemplateApiResult(srcTemplate); - long poolId = pool.getId(); - long templateId = srcTemplate.getId(); - try{ - // create one entry in template_spool_ref - VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); - if (templateStoragePoolRef == null) { - templateStoragePoolRef = new VMTemplateStoragePoolVO(poolId, templateId); - templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef); - } - DataStore destStore = (DataStore)pool; - TemplateInfo destTemplate = this._templateFactory.getTemplate(templateStoragePoolRef.getTemplateId(), destStore); - destTemplate.processEvent(Event.CreateOnlyRequested); - srcTemplate.processEvent(Event.CopyingRequested); - - CopyTemplateContext context = new CopyTemplateContext(null, future, srcTemplate, - destTemplate, - destStore - ); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().prepareTemplateCallBack(null, null)) - .setContext(context); - this._motionSrv.copyAsync(srcTemplate, destTemplate, caller); - } catch (Exception e) { - s_logger.debug("Failed to prepare template on storage pool", e); - res.setResult(e.toString()); - future.complete(res); - } - return future; - } - - - - class CopyTemplateContext extends AsyncRpcConext { - final TemplateInfo srcTemplate; - final TemplateInfo destTemplate; - final DataStore destStore; - final AsyncCallFuture future; - - /** - * @param callback - */ - public CopyTemplateContext(AsyncCompletionCallback callback, AsyncCallFuture future, TemplateInfo srcTemplate, - TemplateInfo destTemplate, DataStore destStore) { - super(callback); - this.srcTemplate = srcTemplate; - this.destTemplate = destTemplate; - this.destStore = destStore; - this.future = future; - } - - public TemplateInfo getSrcTemplate() { - return srcTemplate; - } - - public TemplateInfo getDestTemplate() { - return destTemplate; - } - - public DataStore getDestStore() { - return destStore; - } - - public AsyncCallFuture getFuture() { - return future; - } - } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index d53029a3474..ca9f22c7cb4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -22,12 +22,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; -import com.cloud.agent.api.Answer; import com.cloud.storage.DataStoreRole; import com.cloud.utils.fsm.NoTransitionException; public interface ObjectInDataStoreManager { - public DataObject create(DataObject template, DataStore dataStore); + public DataObject create(DataObject dataObj, DataStore dataStore); + public boolean delete(DataObject dataObj); public DataObject get(DataObject dataObj, DataStore store); public boolean update(DataObject vo, Event event) throws NoTransitionException; DataObjectInStore findObject(long objId, DataObjectType type, diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index bf9a98d08f7..b00d1521cf2 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -157,6 +157,58 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return this.get(obj, dataStore); } + + @Override + public boolean delete(DataObject dataObj) { + long objId = dataObj.getId(); + DataStore dataStore = dataObj.getDataStore(); + if (dataStore.getRole() == DataStoreRole.Primary) { + if ( dataObj.getType() == DataObjectType.TEMPLATE){ + VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId); + if ( destTmpltPool != null ){ + return templatePoolDao.remove(destTmpltPool.getId()); + } else { + s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + ", so no need to delete"); + return true; + } + } + } else { + // Image store + switch ( dataObj.getType()){ + case TEMPLATE: + TemplateDataStoreVO destTmpltStore = templateDataStoreDao.findByStoreTemplate(dataStore.getId(), objId); + if ( destTmpltStore != null ){ + return templateDataStoreDao.remove(destTmpltStore.getId()); + } + else{ + s_logger.warn("Template " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + return true; + } + case SNAPSHOT: + SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getId(), objId); + if ( destSnapshotStore != null ){ + return snapshotDataStoreDao.remove(destSnapshotStore.getId()); + } + else{ + s_logger.warn("Snapshot " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + return true; + } + case VOLUME: + VolumeDataStoreVO destVolumeStore = volumeDataStoreDao.findByStoreVolume(dataStore.getId(), objId); + if ( destVolumeStore != null ){ + return volumeDataStoreDao.remove(destVolumeStore.getId()); + } + else{ + s_logger.warn("Volume " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + return true; + } + } + } + + s_logger.warn("Unsupported data object (" + dataObj.getType() + ", " + dataObj.getDataStore() + ")"); + return false; + } + @Override public boolean update(DataObject data, Event event) throws NoTransitionException { From 29687663e84c06067e8433b4598629aaedebceb4 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 22 Apr 2013 16:15:57 -0700 Subject: [PATCH 048/303] Rename SnapshotStrategy to SnapshotService to have consistent naming convention for Template, Snapshot, Volume. Also rename CopyCmd to CopyCommand to follow internal command naming convention. --- ...otService.java => SnapshotApiService.java} | 2 +- .../org/apache/cloudstack/api/BaseCmd.java | 4 +- .../resource/NfsSecondaryStorageResource.java | 12 +- ...shotStrategy.java => SnapshotService.java} | 3 +- .../{CopyCmd.java => CopyCommand.java} | 4 +- .../motion/AncientDataMotionStrategy.java | 6 +- .../test/DirectAgentManagerSimpleImpl.java | 13 - .../storage/snapshot/SnapshotServiceImpl.java | 568 ++++++++++++++++- .../strategy/AncientSnapshotStrategy.java | 597 ------------------ .../cloudstack/storage/LocalHostEndpoint.java | 4 +- .../resource/XenServerStorageResource.java | 10 +- .../storage/snapshot/SnapshotManagerImpl.java | 109 ++-- 12 files changed, 617 insertions(+), 715 deletions(-) rename api/src/com/cloud/storage/snapshot/{SnapshotService.java => SnapshotApiService.java} (99%) rename engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/{SnapshotStrategy.java => SnapshotService.java} (92%) rename engine/api/src/org/apache/cloudstack/storage/command/{CopyCmd.java => CopyCommand.java} (91%) delete mode 100644 engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java diff --git a/api/src/com/cloud/storage/snapshot/SnapshotService.java b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java similarity index 99% rename from api/src/com/cloud/storage/snapshot/SnapshotService.java rename to api/src/com/cloud/storage/snapshot/SnapshotApiService.java index b5325f52080..23e65220ff9 100644 --- a/api/src/com/cloud/storage/snapshot/SnapshotService.java +++ b/api/src/com/cloud/storage/snapshot/SnapshotApiService.java @@ -31,7 +31,7 @@ import com.cloud.storage.Volume; import com.cloud.user.Account; import com.cloud.utils.Pair; -public interface SnapshotService { +public interface SnapshotApiService { /** * List all snapshots of a disk volume. Optionally lists snapshots created by specified interval diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index b845053e470..46a9dfc1e24 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -64,7 +64,7 @@ import com.cloud.server.TaggedResourceService; import com.cloud.storage.DataStoreProviderApiService; import com.cloud.storage.StorageService; import com.cloud.storage.VolumeApiService; -import com.cloud.storage.snapshot.SnapshotService; +import com.cloud.storage.snapshot.SnapshotApiService; import com.cloud.template.TemplateApiService; import com.cloud.user.Account; import com.cloud.user.AccountService; @@ -108,7 +108,7 @@ public abstract class BaseCmd { @Inject public NetworkService _networkService; @Inject public TemplateApiService _templateService; @Inject public SecurityGroupService _securityGroupService; - @Inject public SnapshotService _snapshotService; + @Inject public SnapshotApiService _snapshotService; @Inject public ConsoleProxyService _consoleProxyService; @Inject public VpcVirtualNetworkApplianceService _routerService; @Inject public ResponseGenerator _responseGenerator; diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index e8abcbf1a67..3be9ced822c 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -48,7 +48,7 @@ import java.util.concurrent.Callable; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; -import org.apache.cloudstack.storage.command.CopyCmd; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -215,14 +215,14 @@ SecondaryStorageResource { return execute((DeleteTemplateFromS3Command) cmd); } else if (cmd instanceof CleanupSnapshotBackupCommand){ return execute((CleanupSnapshotBackupCommand)cmd); - } else if (cmd instanceof CopyCmd) { - return execute((CopyCmd)cmd); + } else if (cmd instanceof CopyCommand) { + return execute((CopyCommand)cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } - protected Answer downloadFromS3ToNfs(CopyCmd cmd, DataTO srcData, S3TO s3, + protected Answer downloadFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); @@ -265,12 +265,12 @@ SecondaryStorageResource { } } - protected Answer downloadFromSwiftToNfs(CopyCmd cmd, DataTO srcData, SwiftTO srcImageStore, + protected Answer downloadFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, DataTO destData, NfsTO destImageStore) { return Answer.createUnsupportedCommandAnswer(cmd); } - protected Answer execute(CopyCmd cmd) { + protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java similarity index 92% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java rename to engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java index e9492c4afc6..68dc55f9a5c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java @@ -18,8 +18,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; -public interface SnapshotStrategy { - public boolean canHandle(SnapshotInfo snapshot); +public interface SnapshotService { public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId); public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); public boolean deleteSnapshot(SnapshotInfo snapshot); diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java similarity index 91% rename from engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java rename to engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index 9cb225b762f..fb280346793 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -20,7 +20,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Command; -public class CopyCmd extends Command implements StorageSubSystemCommand { +public class CopyCommand extends Command implements StorageSubSystemCommand { private DataTO srcTO; private DataTO destTO; private int timeout; @@ -39,7 +39,7 @@ public class CopyCmd extends Command implements StorageSubSystemCommand { this.timeout = timeout; } - public CopyCmd(DataTO srcUri, DataTO destUri, int timeout) { + public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) { super(); this.srcTO = srcUri; this.destTO = destUri; 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 index e72bb54ddec..8274fd75638 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -35,7 +35,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.command.CopyCmd; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; @@ -194,13 +194,13 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { //need to copy it to image cache store DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); - CopyCmd cmd = new CopyCmd(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); EndPoint ep = selector.select(cacheData, destData); Answer answer = ep.sendMessage(cmd); return answer; } else { //handle copy it to cache store - CopyCmd cmd = new CopyCmd(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait); + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait); EndPoint ep = selector.select(srcData, destData); Answer answer = ep.sendMessage(cmd); return answer; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index 0725971ab08..c5b5883e9a3 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -187,19 +187,6 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } - - @Override - public void sendToSecStorage(DataStore ssStore, Command cmd, Listener listener) throws AgentUnavailableException { - // TODO Auto-generated method stub - - } - - @Override - public Answer sendToSecStorage(DataStore ssStore, Command cmd) { - // TODO Auto-generated method stub - return null; - } - @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 1b64fd0cae3..7eee7720330 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -14,29 +14,571 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. + package org.apache.cloudstack.storage.snapshot; -import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +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.PrimaryDataStoreDriver; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.BackupSnapshotAnswer; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.HostVO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.resource.ResourceManager; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.StoragePool; +import com.cloud.storage.VolumeManager; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.snapshot.VMSnapshot; +import com.cloud.vm.snapshot.VMSnapshotVO; +import com.cloud.vm.snapshot.dao.VMSnapshotDao; + @Component public class SnapshotServiceImpl implements SnapshotService { - - public SnapshotServiceImpl() { - + private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class); + @Inject + protected VolumeDao _volsDao; + @Inject + protected UserVmDao _vmDao; + @Inject + protected PrimaryDataStoreDao _storagePoolDao; + @Inject + protected ClusterDao _clusterDao; + @Inject + protected SnapshotDao _snapshotDao; + @Inject + private ResourceManager _resourceMgr; + @Inject + protected SnapshotManager snapshotMgr; + @Inject + protected VolumeManager volumeMgr; + @Inject + private ConfigurationDao _configDao; + @Inject + protected SnapshotStateMachineManager stateMachineManager; + @Inject + private VolumeDao volumeDao; + @Inject + SnapshotDataFactory snapshotfactory; + @Inject + DataStoreManager dataStoreMgr; + @Inject + DataMotionService motionSrv; + @Inject + ObjectInDataStoreManager objInStoreMgr; + @Inject + VMSnapshotDao _vmSnapshotDao; + + + + + static private class CreateSnapshotContext extends AsyncRpcConext { + final VolumeInfo volume; + final SnapshotInfo snapshot; + final AsyncCallFuture future; + public CreateSnapshotContext(AsyncCompletionCallback callback, VolumeInfo volume, + SnapshotInfo snapshot, + AsyncCallFuture future) { + super(callback); + this.volume = volume; + this.snapshot = snapshot; + this.future = future; + } + } + + static private class DeleteSnapshotContext extends AsyncRpcConext { + final SnapshotInfo snapshot; + final AsyncCallFuture future; + public DeleteSnapshotContext(AsyncCompletionCallback callback, SnapshotInfo snapshot, + AsyncCallFuture future) { + super(callback); + this.snapshot = snapshot; + this.future = future; + } + + } + + static private class CopySnapshotContext extends AsyncRpcConext { + final SnapshotInfo srcSnapshot; + final SnapshotInfo destSnapshot; + final AsyncCallFuture future; + public CopySnapshotContext(AsyncCompletionCallback callback, + SnapshotInfo srcSnapshot, + SnapshotInfo destSnapshot, + AsyncCallFuture future) { + super(callback); + this.srcSnapshot = srcSnapshot; + this.destSnapshot = destSnapshot; + this.future = future; + } + + } + + protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher callback, + CreateSnapshotContext context) { + CreateCmdResult result = callback.getResult(); + SnapshotObject snapshot = (SnapshotObject)context.snapshot; + VolumeInfo volume = context.volume; + AsyncCallFuture future = context.future; + SnapshotResult snapResult = new SnapshotResult(snapshot); + if (result.isFailed()) { + s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult()); + try { + snapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + } + + + snapResult.setResult(result.getResult()); + future.complete(snapResult); + return null; + } + + try { + SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); + String preSnapshotPath = null; + if (preSnapshotVO != null) { + preSnapshotPath = preSnapshotVO.getPath(); + } + SnapshotVO snapshotVO = this._snapshotDao.findById(snapshot.getId()); + // The snapshot was successfully created + if (preSnapshotPath != null && preSnapshotPath.equals(result.getPath())) { + // empty snapshot + s_logger.debug("CreateSnapshot: this is empty snapshot "); + + snapshotVO.setPath(preSnapshotPath); + snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); + snapshotVO.setSwiftId(preSnapshotVO.getSwiftId()); + snapshotVO.setPrevSnapshotId(preSnapshotVO.getId()); + snapshotVO.setSecHostId(preSnapshotVO.getSecHostId()); + snapshot.processEvent(Snapshot.Event.OperationNotPerformed); + } else { + long preSnapshotId = 0; + + if (preSnapshotVO != null && preSnapshotVO.getBackupSnapshotId() != null) { + preSnapshotId = preSnapshotVO.getId(); + int _deltaSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX); + int deltaSnap = _deltaSnapshotMax; + + int i; + for (i = 1; i < deltaSnap; i++) { + String prevBackupUuid = preSnapshotVO.getBackupSnapshotId(); + // previous snapshot doesn't have backup, create a full snapshot + if (prevBackupUuid == null) { + preSnapshotId = 0; + break; + } + long preSSId = preSnapshotVO.getPrevSnapshotId(); + if (preSSId == 0) { + break; + } + preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId); + } + if (i >= deltaSnap) { + preSnapshotId = 0; + } + } + + //If the volume is moved around, backup a full snapshot to secondary storage + if (volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId())) { + preSnapshotId = 0; + //TODO: fix this hack + VolumeVO volumeVO = this.volumeDao.findById(volume.getId()); + volumeVO.setLastPoolId(volume.getPoolId()); + this.volumeDao.update(volume.getId(), volumeVO); + } + + snapshot.setPath(result.getPath()); + snapshot.setPrevSnapshotId(preSnapshotId); + + snapshot.processEvent(Snapshot.Event.OperationSucceeded); + snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(snapshot.getId())); + } + } catch (Exception e) { + s_logger.debug("Failed to create snapshot: ", e); + snapResult.setResult(e.toString()); + try { + snapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change snapshot state: " + e1.toString()); + } + } + + future.complete(snapResult); + return null; + } + + class SnapshotResult extends CommandResult { + SnapshotInfo snashot; + public SnapshotResult(SnapshotInfo snapshot) { + this.snashot = snapshot; + } + } + + protected SnapshotInfo createSnapshotOnPrimary(VolumeInfo volume, Long snapshotId) { + SnapshotObject snapshot = (SnapshotObject)this.snapshotfactory.getSnapshot(snapshotId); + if (snapshot == null) { + throw new CloudRuntimeException("Can not find snapshot " + snapshotId); + } + + try { + snapshot.processEvent(Snapshot.Event.CreateRequested); + } catch (NoTransitionException nte) { + s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage()); + } + + AsyncCallFuture future = new AsyncCallFuture(); + try { + CreateSnapshotContext context = new CreateSnapshotContext( + null, volume, snapshot, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setCallback( + caller.getTarget().createSnapshotAsyncCallback(null, null)) + .setContext(context); + PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver(); + primaryStore.takeSnapshot(snapshot, caller); + } catch (Exception e) { + s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); + try { + snapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change state for event: OperationFailed" , e); + } + throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId()); + } + + SnapshotResult result; + + try { + result = future.get(); + if (result.isFailed()) { + s_logger.debug("Failed to create snapshot:" + result.getResult()); + throw new CloudRuntimeException(result.getResult()); + } + return result.snashot; + } catch (InterruptedException e) { + s_logger.debug("Failed to create snapshot", e); + throw new CloudRuntimeException("Failed to create snapshot", e); + } catch (ExecutionException e) { + s_logger.debug("Failed to create snapshot", e); + throw new CloudRuntimeException("Failed to create snapshot", e); + } + + } + + private boolean hostSupportSnapsthot(HostVO host) { + if (host.getHypervisorType() != HypervisorType.KVM) { + return true; + } + // Determine host capabilities + String caps = host.getCapabilities(); + + if (caps != null) { + String[] tokens = caps.split(","); + for (String token : tokens) { + if (token.contains("snapshot")) { + return true; + } + } + } + return false; + } + + protected boolean supportedByHypervisor(VolumeInfo volume) { + if (volume.getHypervisorType().equals(HypervisorType.KVM)) { + StoragePool storagePool = (StoragePool)volume.getDataStore(); + ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId()); + List hosts = _resourceMgr.listAllHostsInCluster(cluster.getId()); + if (hosts != null && !hosts.isEmpty()) { + HostVO host = hosts.get(0); + if (!hostSupportSnapsthot(host)) { + throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId()); + } + } + } + + // if volume is attached to a vm in destroyed or expunging state; disallow + if (volume.getInstanceId() != null) { + UserVmVO userVm = _vmDao.findById(volume.getInstanceId()); + if (userVm != null) { + if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) { + throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in " + + userVm.getState().toString() + " state"); + } + + if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) { + List activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); + if(activeSnapshots.size() > 1) + throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); + } + + List activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), + VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging); + if (activeVMSnapshots.size() > 0) { + throw new CloudRuntimeException( + "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later"); + } + } + } + + return true; } @Override - public SnapshotEntity getSnapshotEntity(long snapshotId) { - // TODO Auto-generated method stub + public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId) { + + supportedByHypervisor(volume); + + SnapshotInfo snapshot = createSnapshotOnPrimary(volume, snapshotId); + return snapshot; + } + + @Override + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { + SnapshotObject snapObj = (SnapshotObject)snapshot; + AsyncCallFuture future = new AsyncCallFuture(); + SnapshotResult result = new SnapshotResult(snapshot); + try { + + snapObj.processEvent(Snapshot.Event.BackupToSecondary); + + ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); + List stores = this.dataStoreMgr.getImageStoresByScope(scope); + if (stores.size() != 1) { + throw new CloudRuntimeException("find out more than one image stores"); + } + + DataStore imageStore = stores.get(0); + SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot); + + snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); + CopySnapshotContext context = new CopySnapshotContext(null, snapshot, + snapshotOnImageStore, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setCallback( + caller.getTarget().copySnapshotAsyncCallback(null, null)) + .setContext(context); + this.motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller); + } catch (Exception e) { + s_logger.debug("Failed to copy snapshot", e); + result.setResult("Failed to copy snapshot:" +e.toString()); + try { + snapObj.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change state: " + e1.toString()); + } + future.complete(result); + } + + try { + SnapshotResult res = future.get(); + SnapshotInfo destSnapshot = res.snashot; + return destSnapshot; + } catch (InterruptedException e) { + s_logger.debug("failed copy snapshot", e); + throw new CloudRuntimeException("Failed to copy snapshot" , e); + } catch (ExecutionException e) { + s_logger.debug("Failed to copy snapshot", e); + throw new CloudRuntimeException("Failed to copy snapshot" , e); + } + + } + + protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher callback, + CopySnapshotContext context) { + CopyCommandResult result = callback.getResult(); + SnapshotInfo destSnapshot = context.destSnapshot; + SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot; + AsyncCallFuture future = context.future; + SnapshotResult snapResult = new SnapshotResult(destSnapshot); + if (result.isFailed()) { + snapResult.setResult(result.getResult()); + future.complete(snapResult); + return null; + } + + try { + BackupSnapshotAnswer answer = (BackupSnapshotAnswer)result.getAnswer(); + + DataObjectInStore dataInStore = objInStoreMgr.findObject(destSnapshot, destSnapshot.getDataStore()); + dataInStore.setInstallPath(answer.getBackupSnapshotName()); + objInStoreMgr.update(destSnapshot, Event.OperationSuccessed); + + srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); + snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId())); + future.complete(snapResult); + } catch (Exception e) { + s_logger.debug("Failed to update snapshot state", e); + snapResult.setResult(e.toString()); + future.complete(snapResult); + } + return null; + } + + @DB + protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { + DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image); + if (store == null) { + s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); + return false; + } + + try { + SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store); + snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + + AsyncCallFuture future = new AsyncCallFuture(); + DeleteSnapshotContext context = new DeleteSnapshotContext(null, + snapshotInfo, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setCallback( + caller.getTarget().deleteSnapshotCallback(null, null)) + .setContext(context); + + store.getDriver().deleteAsync(snapshotInfo, caller); + + SnapshotResult result = future.get(); + if (result.isFailed()) { + s_logger.debug("Failed to delete snapsoht: " + result.getResult()); + } + return result.isSuccess(); + } catch (Exception e) { + s_logger.debug("Failed to delete snapshot", e); + return false; + } + } + + protected Void deleteSnapshotCallback(AsyncCallbackDispatcher callback, + DeleteSnapshotContext context) { + CommandResult result = callback.getResult(); + AsyncCallFuture future = context.future; + SnapshotInfo snapshot = context.snapshot; + if (result.isFailed()) { + s_logger.debug("delete snapshot failed" + result.getResult()); + snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); + SnapshotResult res = new SnapshotResult(context.snapshot); + future.complete(res); + return null; + } + snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); + SnapshotResult res = new SnapshotResult(context.snapshot); + future.complete(res); return null; } @Override - public boolean takeSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; + public boolean deleteSnapshot(SnapshotInfo snapInfo) { + Long snapshotId = snapInfo.getId(); + SnapshotObject snapshot = (SnapshotObject)snapInfo; + + if (!Snapshot.State.BackedUp.equals(snapshot.getState())) { + throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); + } + SnapshotVO lastSnapshot = null; + if (snapshot.getBackupSnapshotId() != null) { + List snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId()); + if (snaps != null && snaps.size() > 1) { + snapshot.setBackupSnapshotId(null); + SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId); + _snapshotDao.update(snapshot.getId(), snapshotVO); + } + } + + _snapshotDao.remove(snapshotId); + + long lastId = snapshotId; + boolean destroy = false; + while (true) { + lastSnapshot = _snapshotDao.findNextSnapshot(lastId); + if (lastSnapshot == null) { + // if all snapshots after this snapshot in this chain are removed, remove those snapshots. + destroy = true; + break; + } + if (lastSnapshot.getRemoved() == null) { + // if there is one child not removed, then can not remove back up snapshot. + break; + } + lastId = lastSnapshot.getId(); + } + if (destroy) { + lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); + while (lastSnapshot.getRemoved() != null) { + String BackupSnapshotId = lastSnapshot.getBackupSnapshotId(); + if (BackupSnapshotId != null) { + List snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId); + if (snaps != null && snaps.size() > 1) { + lastSnapshot.setBackupSnapshotId(null); + _snapshotDao.update(lastSnapshot.getId(), lastSnapshot); + } else { + if (destroySnapshotBackUp(lastSnapshot)) { + + } else { + s_logger.debug("Destroying snapshot backup failed " + lastSnapshot); + break; + } + } + } + lastId = lastSnapshot.getPrevSnapshotId(); + if (lastId == 0) { + break; + } + lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); + } + } + return true; + } @Override @@ -45,12 +587,4 @@ public class SnapshotServiceImpl implements SnapshotService { return false; } - @Override - public boolean deleteSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; - } - - - } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java deleted file mode 100644 index 944c477d2c7..00000000000 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/strategy/AncientSnapshotStrategy.java +++ /dev/null @@ -1,597 +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.snapshot.strategy; - -import java.util.List; -import java.util.concurrent.ExecutionException; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -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.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.framework.async.AsyncCallFuture; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.snapshot.SnapshotObject; -import org.apache.cloudstack.storage.snapshot.SnapshotStateMachineManager; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.host.HostVO; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.resource.ResourceManager; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.StoragePool; -import com.cloud.storage.VolumeManager; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.db.DB; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.snapshot.VMSnapshot; -import com.cloud.vm.snapshot.VMSnapshotVO; -import com.cloud.vm.snapshot.dao.VMSnapshotDao; - -@Component -public class AncientSnapshotStrategy implements SnapshotStrategy { - private static final Logger s_logger = Logger.getLogger(AncientSnapshotStrategy.class); - @Inject - protected VolumeDao _volsDao; - @Inject - protected UserVmDao _vmDao; - @Inject - protected PrimaryDataStoreDao _storagePoolDao; - @Inject - protected ClusterDao _clusterDao; - @Inject - protected SnapshotDao snapshotDao; - @Inject - private ResourceManager _resourceMgr; - @Inject - protected SnapshotDao _snapshotDao; - @Inject - protected SnapshotManager snapshotMgr; - @Inject - protected VolumeManager volumeMgr; - @Inject - private ConfigurationDao _configDao; - @Inject - protected SnapshotStateMachineManager stateMachineManager; - @Inject - private VolumeDao volumeDao; - @Inject - SnapshotDataFactory snapshotfactory; - @Inject - DataStoreManager dataStoreMgr; - @Inject - DataMotionService motionSrv; - @Inject - ObjectInDataStoreManager objInStoreMgr; - @Inject - VMSnapshotDao _vmSnapshotDao; - - - @Override - public boolean canHandle(SnapshotInfo snapshot) { - return true; - } - - static private class CreateSnapshotContext extends AsyncRpcConext { - final VolumeInfo volume; - final SnapshotInfo snapshot; - final AsyncCallFuture future; - public CreateSnapshotContext(AsyncCompletionCallback callback, VolumeInfo volume, - SnapshotInfo snapshot, - AsyncCallFuture future) { - super(callback); - this.volume = volume; - this.snapshot = snapshot; - this.future = future; - } - } - - static private class DeleteSnapshotContext extends AsyncRpcConext { - final SnapshotInfo snapshot; - final AsyncCallFuture future; - public DeleteSnapshotContext(AsyncCompletionCallback callback, SnapshotInfo snapshot, - AsyncCallFuture future) { - super(callback); - this.snapshot = snapshot; - this.future = future; - } - - } - - static private class CopySnapshotContext extends AsyncRpcConext { - final SnapshotInfo srcSnapshot; - final SnapshotInfo destSnapshot; - final AsyncCallFuture future; - public CopySnapshotContext(AsyncCompletionCallback callback, - SnapshotInfo srcSnapshot, - SnapshotInfo destSnapshot, - AsyncCallFuture future) { - super(callback); - this.srcSnapshot = srcSnapshot; - this.destSnapshot = destSnapshot; - this.future = future; - } - - } - - protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher callback, - CreateSnapshotContext context) { - CreateCmdResult result = callback.getResult(); - SnapshotObject snapshot = (SnapshotObject)context.snapshot; - VolumeInfo volume = context.volume; - AsyncCallFuture future = context.future; - SnapshotResult snapResult = new SnapshotResult(snapshot); - if (result.isFailed()) { - s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult()); - try { - snapshot.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException nte) { - s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); - } - - - snapResult.setResult(result.getResult()); - future.complete(snapResult); - return null; - } - - try { - SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); - String preSnapshotPath = null; - if (preSnapshotVO != null) { - preSnapshotPath = preSnapshotVO.getPath(); - } - SnapshotVO snapshotVO = this.snapshotDao.findById(snapshot.getId()); - // The snapshot was successfully created - if (preSnapshotPath != null && preSnapshotPath.equals(result.getPath())) { - // empty snapshot - s_logger.debug("CreateSnapshot: this is empty snapshot "); - - snapshotVO.setPath(preSnapshotPath); - snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); - snapshotVO.setSwiftId(preSnapshotVO.getSwiftId()); - snapshotVO.setPrevSnapshotId(preSnapshotVO.getId()); - snapshotVO.setSecHostId(preSnapshotVO.getSecHostId()); - snapshot.processEvent(Snapshot.Event.OperationNotPerformed); - } else { - long preSnapshotId = 0; - - if (preSnapshotVO != null && preSnapshotVO.getBackupSnapshotId() != null) { - preSnapshotId = preSnapshotVO.getId(); - int _deltaSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX); - int deltaSnap = _deltaSnapshotMax; - - int i; - for (i = 1; i < deltaSnap; i++) { - String prevBackupUuid = preSnapshotVO.getBackupSnapshotId(); - // previous snapshot doesn't have backup, create a full snapshot - if (prevBackupUuid == null) { - preSnapshotId = 0; - break; - } - long preSSId = preSnapshotVO.getPrevSnapshotId(); - if (preSSId == 0) { - break; - } - preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId); - } - if (i >= deltaSnap) { - preSnapshotId = 0; - } - } - - //If the volume is moved around, backup a full snapshot to secondary storage - if (volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId())) { - preSnapshotId = 0; - //TODO: fix this hack - VolumeVO volumeVO = this.volumeDao.findById(volume.getId()); - volumeVO.setLastPoolId(volume.getPoolId()); - this.volumeDao.update(volume.getId(), volumeVO); - } - - snapshot.setPath(result.getPath()); - snapshot.setPrevSnapshotId(preSnapshotId); - - snapshot.processEvent(Snapshot.Event.OperationSucceeded); - snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(snapshot.getId())); - } - } catch (Exception e) { - s_logger.debug("Failed to create snapshot: ", e); - snapResult.setResult(e.toString()); - try { - snapshot.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException e1) { - s_logger.debug("Failed to change snapshot state: " + e1.toString()); - } - } - - future.complete(snapResult); - return null; - } - - class SnapshotResult extends CommandResult { - SnapshotInfo snashot; - public SnapshotResult(SnapshotInfo snapshot) { - this.snashot = snapshot; - } - } - - protected SnapshotInfo createSnapshotOnPrimary(VolumeInfo volume, Long snapshotId) { - SnapshotObject snapshot = (SnapshotObject)this.snapshotfactory.getSnapshot(snapshotId); - if (snapshot == null) { - throw new CloudRuntimeException("Can not find snapshot " + snapshotId); - } - - try { - snapshot.processEvent(Snapshot.Event.CreateRequested); - } catch (NoTransitionException nte) { - s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); - throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage()); - } - - AsyncCallFuture future = new AsyncCallFuture(); - try { - CreateSnapshotContext context = new CreateSnapshotContext( - null, volume, snapshot, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().createSnapshotAsyncCallback(null, null)) - .setContext(context); - PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver(); - primaryStore.takeSnapshot(snapshot, caller); - } catch (Exception e) { - s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); - try { - snapshot.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException e1) { - s_logger.debug("Failed to change state for event: OperationFailed" , e); - } - throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId()); - } - - SnapshotResult result; - - try { - result = future.get(); - if (result.isFailed()) { - s_logger.debug("Failed to create snapshot:" + result.getResult()); - throw new CloudRuntimeException(result.getResult()); - } - return result.snashot; - } catch (InterruptedException e) { - s_logger.debug("Failed to create snapshot", e); - throw new CloudRuntimeException("Failed to create snapshot", e); - } catch (ExecutionException e) { - s_logger.debug("Failed to create snapshot", e); - throw new CloudRuntimeException("Failed to create snapshot", e); - } - - } - - private boolean hostSupportSnapsthot(HostVO host) { - if (host.getHypervisorType() != HypervisorType.KVM) { - return true; - } - // Determine host capabilities - String caps = host.getCapabilities(); - - if (caps != null) { - String[] tokens = caps.split(","); - for (String token : tokens) { - if (token.contains("snapshot")) { - return true; - } - } - } - return false; - } - - protected boolean supportedByHypervisor(VolumeInfo volume) { - if (volume.getHypervisorType().equals(HypervisorType.KVM)) { - StoragePool storagePool = (StoragePool)volume.getDataStore(); - ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId()); - List hosts = _resourceMgr.listAllHostsInCluster(cluster.getId()); - if (hosts != null && !hosts.isEmpty()) { - HostVO host = hosts.get(0); - if (!hostSupportSnapsthot(host)) { - throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId()); - } - } - } - - // if volume is attached to a vm in destroyed or expunging state; disallow - if (volume.getInstanceId() != null) { - UserVmVO userVm = _vmDao.findById(volume.getInstanceId()); - if (userVm != null) { - if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) { - throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in " - + userVm.getState().toString() + " state"); - } - - if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) { - List activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); - if(activeSnapshots.size() > 1) - throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); - } - - List activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), - VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging); - if (activeVMSnapshots.size() > 0) { - throw new CloudRuntimeException( - "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later"); - } - } - } - - return true; - } - - @Override - public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId) { - - supportedByHypervisor(volume); - - SnapshotInfo snapshot = createSnapshotOnPrimary(volume, snapshotId); - return snapshot; - } - - @Override - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { - SnapshotObject snapObj = (SnapshotObject)snapshot; - AsyncCallFuture future = new AsyncCallFuture(); - SnapshotResult result = new SnapshotResult(snapshot); - try { - - snapObj.processEvent(Snapshot.Event.BackupToSecondary); - - ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); - List stores = this.dataStoreMgr.getImageStoresByScope(scope); - if (stores.size() != 1) { - throw new CloudRuntimeException("find out more than one image stores"); - } - - DataStore imageStore = stores.get(0); - SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot); - - snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); - CopySnapshotContext context = new CopySnapshotContext(null, snapshot, - snapshotOnImageStore, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().copySnapshotAsyncCallback(null, null)) - .setContext(context); - this.motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller); - } catch (Exception e) { - s_logger.debug("Failed to copy snapshot", e); - result.setResult("Failed to copy snapshot:" +e.toString()); - try { - snapObj.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException e1) { - s_logger.debug("Failed to change state: " + e1.toString()); - } - future.complete(result); - } - - try { - SnapshotResult res = future.get(); - SnapshotInfo destSnapshot = res.snashot; - return destSnapshot; - } catch (InterruptedException e) { - s_logger.debug("failed copy snapshot", e); - throw new CloudRuntimeException("Failed to copy snapshot" , e); - } catch (ExecutionException e) { - s_logger.debug("Failed to copy snapshot", e); - throw new CloudRuntimeException("Failed to copy snapshot" , e); - } - - } - - protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher callback, - CopySnapshotContext context) { - CopyCommandResult result = callback.getResult(); - SnapshotInfo destSnapshot = context.destSnapshot; - SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot; - AsyncCallFuture future = context.future; - SnapshotResult snapResult = new SnapshotResult(destSnapshot); - if (result.isFailed()) { - snapResult.setResult(result.getResult()); - future.complete(snapResult); - return null; - } - - try { - BackupSnapshotAnswer answer = (BackupSnapshotAnswer)result.getAnswer(); - - DataObjectInStore dataInStore = objInStoreMgr.findObject(destSnapshot, destSnapshot.getDataStore()); - dataInStore.setInstallPath(answer.getBackupSnapshotName()); - objInStoreMgr.update(destSnapshot, Event.OperationSuccessed); - - srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); - snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId())); - future.complete(snapResult); - } catch (Exception e) { - s_logger.debug("Failed to update snapshot state", e); - snapResult.setResult(e.toString()); - future.complete(snapResult); - } - return null; - } - - @DB - protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { - DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image); - if (store == null) { - s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); - return false; - } - - try { - SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store); - snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); - - AsyncCallFuture future = new AsyncCallFuture(); - DeleteSnapshotContext context = new DeleteSnapshotContext(null, - snapshotInfo, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().deleteSnapshotCallback(null, null)) - .setContext(context); - - store.getDriver().deleteAsync(snapshotInfo, caller); - - SnapshotResult result = future.get(); - if (result.isFailed()) { - s_logger.debug("Failed to delete snapsoht: " + result.getResult()); - } - return result.isSuccess(); - } catch (Exception e) { - s_logger.debug("Failed to delete snapshot", e); - return false; - } - } - - protected Void deleteSnapshotCallback(AsyncCallbackDispatcher callback, - DeleteSnapshotContext context) { - CommandResult result = callback.getResult(); - AsyncCallFuture future = context.future; - SnapshotInfo snapshot = context.snapshot; - if (result.isFailed()) { - s_logger.debug("delete snapshot failed" + result.getResult()); - snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); - SnapshotResult res = new SnapshotResult(context.snapshot); - future.complete(res); - return null; - } - snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); - SnapshotResult res = new SnapshotResult(context.snapshot); - future.complete(res); - return null; - } - - @Override - public boolean deleteSnapshot(SnapshotInfo snapInfo) { - Long snapshotId = snapInfo.getId(); - SnapshotObject snapshot = (SnapshotObject)snapInfo; - - if (!Snapshot.State.BackedUp.equals(snapshot.getState())) { - throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); - } - SnapshotVO lastSnapshot = null; - if (snapshot.getBackupSnapshotId() != null) { - List snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId()); - if (snaps != null && snaps.size() > 1) { - snapshot.setBackupSnapshotId(null); - SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId); - _snapshotDao.update(snapshot.getId(), snapshotVO); - } - } - - _snapshotDao.remove(snapshotId); - - long lastId = snapshotId; - boolean destroy = false; - while (true) { - lastSnapshot = _snapshotDao.findNextSnapshot(lastId); - if (lastSnapshot == null) { - // if all snapshots after this snapshot in this chain are removed, remove those snapshots. - destroy = true; - break; - } - if (lastSnapshot.getRemoved() == null) { - // if there is one child not removed, then can not remove back up snapshot. - break; - } - lastId = lastSnapshot.getId(); - } - if (destroy) { - lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); - while (lastSnapshot.getRemoved() != null) { - String BackupSnapshotId = lastSnapshot.getBackupSnapshotId(); - if (BackupSnapshotId != null) { - List snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId); - if (snaps != null && snaps.size() > 1) { - lastSnapshot.setBackupSnapshotId(null); - _snapshotDao.update(lastSnapshot.getId(), lastSnapshot); - } else { - if (destroySnapshotBackUp(lastSnapshot)) { - - } else { - s_logger.debug("Destroying snapshot backup failed " + lastSnapshot); - break; - } - } - } - lastId = lastSnapshot.getPrevSnapshotId(); - if (lastId == 0) { - break; - } - lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); - } - } - return true; - - } - - @Override - public boolean revertSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; - } - -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index f08a5977b2e..9fe0c552850 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -6,7 +6,7 @@ import java.util.concurrent.TimeUnit; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.command.CopyCmd; +import org.apache.cloudstack.storage.command.CopyCommand; import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; @@ -32,7 +32,7 @@ public class LocalHostEndpoint implements EndPoint { @Override public Answer sendMessage(Command cmd) { - if (cmd instanceof CopyCmd) { + if (cmd instanceof CopyCommand) { return resource.executeRequest(cmd); } // TODO Auto-generated method stub diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index e7c009b00b1..300daa597a2 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -34,7 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; -import org.apache.cloudstack.storage.command.CopyCmd; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; @@ -84,8 +84,8 @@ public class XenServerStorageResource { } public Answer handleStorageCommands(StorageSubSystemCommand command) { - if (command instanceof CopyCmd) { - return this.execute((CopyCmd)command); + if (command instanceof CopyCommand) { + return this.execute((CopyCommand)command); } else if (command instanceof AttachPrimaryDataStoreCmd) { return this.execute((AttachPrimaryDataStoreCmd)command); } else if (command instanceof CreatePrimaryDataStoreCmd) { @@ -505,7 +505,7 @@ public class XenServerStorageResource { } - protected Answer directDownloadHttpTemplate(CopyCmd cmd, DecodedDataObject srcObj, DecodedDataObject destObj) { + protected Answer directDownloadHttpTemplate(CopyCommand cmd, DecodedDataObject srcObj, DecodedDataObject destObj) { Connection conn = hypervisorResource.getConnection(); SR poolsr = null; VDI vdi = null; @@ -724,7 +724,7 @@ public class XenServerStorageResource { } - protected Answer execute(CopyCmd cmd) { + protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 3a453d50a72..88bcc6ac19d 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -34,7 +34,7 @@ import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -126,8 +126,8 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.snapshot.dao.VMSnapshotDao; @Component -@Local(value = { SnapshotManager.class, SnapshotService.class }) -public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotService { +@Local(value = { SnapshotManager.class, SnapshotApiService.class }) +public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SnapshotApiService { private static final Logger s_logger = Logger.getLogger(SnapshotManagerImpl.class); @Inject protected VMTemplateDao _templateDao; @@ -171,9 +171,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, private ResourceLimitService _resourceLimitMgr; @Inject private SwiftManager _swiftMgr; - @Inject + @Inject private S3Manager _s3Mgr; - @Inject + @Inject private SecondaryStorageVmManager _ssvmMgr; @Inject private DomainManager _domainMgr; @@ -182,17 +182,17 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Inject private ConfigurationDao _configDao; - @Inject + @Inject private VMSnapshotDao _vmSnapshotDao; String _name; @Inject TemplateManager templateMgr; @Inject VolumeManager volumeMgr; @Inject DataStoreManager dataStoreMgr; - @Inject List snapshotStrategies; + @Inject SnapshotService snapshotSrv; @Inject VolumeDataFactory volFactory; @Inject SnapshotDataFactory snapshotFactory; - + private int _totalRetries; private int _pauseInterval; @@ -201,14 +201,14 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, protected SearchBuilder PolicySnapshotSearch; protected SearchBuilder PoliciesForSnapSearch; - + @Override public Answer sendToPool(Volume vol, Command cmd) { StoragePool pool = (StoragePool)dataStoreMgr.getPrimaryDataStore(vol.getPoolId()); long[] hostIdsToTryFirst = null; - + Long vmHostId = getHostIdForSnapshotOperation(vol); - + if (vmHostId != null) { hostIdsToTryFirst = new long[] { vmHostId }; } @@ -263,29 +263,22 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (volume == null) { throw new InvalidParameterValueException("No such volume exist"); } - + if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException("Volume is not in ready state"); } - + SnapshotInfo snapshot = null; - + boolean backedUp = false; // does the caller have the authority to act on this volume _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume); - + SnapshotInfo snap = this.snapshotFactory.getSnapshot(snapshotId); - SnapshotStrategy strategy = null; - for (SnapshotStrategy st : snapshotStrategies) { - if (st.canHandle(snap)) { - strategy = st; - break; - } - } try { - snapshot = strategy.takeSnapshot(volume, snapshotId); + snapshot = this.snapshotSrv.takeSnapshot(volume, snapshotId); if (snapshot != null) { postCreateSnapshot(volumeId, snapshot.getId(), policyId); //Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event @@ -344,20 +337,13 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (snapshot == null) { throw new CloudRuntimeException("Can't find snapshot:" + snapshotId); } - + if (snapshot.getState() == Snapshot.State.BackedUp) { return snapshot; } - - SnapshotStrategy strategy = null; - for (SnapshotStrategy st : snapshotStrategies) { - if (st.canHandle(snapshot)) { - strategy = st; - break; - } - } - - return strategy.backupSnapshot(snapshot); + + + return this.snapshotSrv.backupSnapshot(snapshot); } @Override @@ -394,7 +380,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } catch (Exception e) { throw new CloudRuntimeException("downloadSnapshotsFromSwift failed due to " + e.toString()); } - + } private List determineBackupUuids(final SnapshotVO snapshot) { @@ -445,7 +431,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } } - + @Override public SnapshotVO getParentSnapshot(VolumeInfo volume, Snapshot snapshot) { long preId = _snapshotDao.getLastSnapshot(volume.getId(), snapshot.getId()); @@ -454,7 +440,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (preId != 0 && !(volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId()))) { preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preId); } - + return preSnapshotVO; } @@ -475,7 +461,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, snapshotSchedule.setSnapshotId(snapshotId); _snapshotScheduleDao.update(snapshotSchedule.getId(), snapshotSchedule); } - + if (snapshot != null && snapshot.isRecursive()) { postCreateRecurringSnapshotForPolicy(userId, volumeId, snapshotId, policyId); } @@ -515,18 +501,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (snapshotCheck == null) { throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId); } - + _accountMgr.checkAccess(caller, null, true, snapshotCheck); - - SnapshotStrategy strategy = null; - for (SnapshotStrategy st : snapshotStrategies) { - if (st.canHandle(snapshotCheck)) { - strategy = st; - break; - } - } + try { - boolean result = strategy.deleteSnapshot(snapshotCheck); + boolean result = this.snapshotSrv.deleteSnapshot(snapshotCheck); if (result) { if (snapshotCheck.getState() == Snapshot.State.BackedUp) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshotCheck.getAccountId(), @@ -573,7 +552,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String snapshotTypeStr = cmd.getSnapshotType(); String intervalTypeStr = cmd.getIntervalType(); Map tags = cmd.getTags(); - + Account caller = UserContext.current().getCaller(); List permittedAccounts = new ArrayList(); @@ -589,8 +568,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, _accountMgr.buildACLSearchParameters(caller, id, cmd.getAccountName(), cmd.getProjectId(), permittedAccounts, domainIdRecursiveListProject, cmd.listAll(), false); Long domainId = domainIdRecursiveListProject.first(); Boolean isRecursive = domainIdRecursiveListProject.second(); - ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); - + ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third(); + Filter searchFilter = new Filter(SnapshotVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal()); SearchBuilder sb = _snapshotDao.createSearchBuilder(); _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -601,7 +580,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); sb.and("snapshotTypeEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.IN); sb.and("snapshotTypeNEQ", sb.entity().getsnapshotType(), SearchCriteria.Op.NEQ); - + if (tags != null && !tags.isEmpty()) { SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); for (int count=0; count < tags.size(); count++) { @@ -620,7 +599,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (volumeId != null) { sc.setParameters("volumeId", volumeId); } - + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Snapshot.toString()); @@ -765,9 +744,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (volume == null) { throw new InvalidParameterValueException("Failed to create snapshot policy, unable to find a volume with id " + volumeId); } - + _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume); - + if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); } @@ -823,7 +802,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (owner.getType() == Account.ACCOUNT_TYPE_PROJECT) { message = "domain/project"; } - + throw new InvalidParameterValueException("Max number of snapshots shouldn't exceed the " + message + " level snapshot limit"); } @@ -869,11 +848,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, return new Pair, Integer>(result.first(), result.second()); } - + private List listPoliciesforVolume(long volumeId) { return _snapshotPolicyDao.listByVolumeId(volumeId); } - + private List listSnapsforVolume(long volumeId) { return _snapshotDao.listByVolumeId(volumeId); } @@ -961,7 +940,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Override public SnapshotVO allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException { Account caller = UserContext.current().getCaller(); - + VolumeVO volume = _volsDao.findById(volumeId); if (volume == null) { throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); @@ -970,11 +949,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if (zone == null) { throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId()); } - + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName()); } - + if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); } @@ -985,7 +964,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported"); } } - + StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId()); if (storagePoolVO == null) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it"); @@ -1030,7 +1009,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString; // Create the Snapshot object and save it so we can return it to the - // user + // user HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId); SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), null, snapshotName, (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType); @@ -1050,7 +1029,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Override public boolean configure(String name, Map params) throws ConfigurationException { - + String value = _configDao.getValue(Config.BackupSnapshotWait.toString()); _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); backup = Boolean.parseBoolean(this._configDao.getValue(Config.BackupSnapshotAferTakingSnapshot.toString())); @@ -1124,7 +1103,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, return success; } - + @Override public boolean canOperateOnVolume(Volume volume) { List snapshots = _snapshotDao.listByStatus(volume.getId(), Snapshot.State.Creating, From b8c5c67fbc074f4a2a015d28760fa0d2a7a35744 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 22 Apr 2013 19:12:50 -0700 Subject: [PATCH 049/303] add copycommand at resouce side --- .../resource/NfsSecondaryStorageResource.java | 49 +++++-- .../storage/command/CopyCmdAnswer.java | 19 ++- .../storage/command/CopyCommand.java | 16 +-- .../storage/to/TemplateObjectTO.java | 20 ++- .../cloudstack/storage/to/VolumeObjectTO.java | 34 ++++- .../manager/StorageCacheManagerImpl.java | 23 ++-- .../motion/AncientDataMotionStrategy.java | 43 +------ .../storage/image/store/TemplateObject.java | 12 +- .../test/DirectAgentManagerSimpleImpl.java | 1 + .../storage/volume/VolumeObject.java | 18 ++- .../storage/volume/VolumeServiceImpl.java | 7 +- .../resource/XenServerStorageResource.java | 121 ++++++++++-------- .../CloudStackImageStoreDriverImpl.java | 3 +- 13 files changed, 207 insertions(+), 159 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 3be9ced822c..b47421031be 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -47,8 +47,11 @@ import java.util.concurrent.Callable; import javax.naming.ConfigurationException; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -222,7 +225,9 @@ SecondaryStorageResource { } } - protected Answer downloadFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, + + protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, + DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); @@ -240,10 +245,10 @@ SecondaryStorageResource { + "download directory %1$s for download from S3.", downloadDirectory.getName() ); s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); + return new CopyCmdAnswer(errMsg); } - getDirectory(s3, s3.getBucketName(), + List files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() { @Override @@ -252,20 +257,42 @@ SecondaryStorageResource { } }); - return new Answer(cmd, true, format("Successfully downloaded " - + "from S3 to directory %2$s", - downloadDirectory.getName())); - + //find out template name + File destFile = null; + for (File f : files) { + if (!f.getName().endsWith(".properties")) { + destFile = f; + break; + } + } + + if (destFile == null) { + return new CopyCmdAnswer("Can't find template"); + } + + DataTO newDestTO = null; + + if (destData.getObjectType() == DataObjectType.TEMPLATE) { + TemplateObjectTO newTemplTO = new TemplateObjectTO(); + newTemplTO.setPath(destPath + File.separator + destFile.getName()); + newTemplTO.setName(destFile.getName()); + newDestTO = newTemplTO; + } else { + return new CopyCmdAnswer("not implemented yet"); + } + + return new CopyCmdAnswer(newDestTO); } catch (Exception e) { final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage()); s_logger.error(errMsg, e); - return new Answer(cmd, false, errMsg); + return new CopyCmdAnswer(errMsg); } } - protected Answer downloadFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, + protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, + DataTO destData, NfsTO destImageStore) { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -286,10 +313,10 @@ SecondaryStorageResource { } if (srcDataStore instanceof S3TO) { - return downloadFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, + return copyFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, destData, (NfsTO)destDataStore); } else if (srcDataStore instanceof SwiftTO) { - return downloadFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, + return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, destData, (NfsTO)destDataStore); } else { return Answer.createUnsupportedCommandAnswer(cmd); diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java index 53e082e6950..4105d624107 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java @@ -16,18 +16,23 @@ // under the License. package org.apache.cloudstack.storage.command; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; + import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; public class CopyCmdAnswer extends Answer { - private final String path; + private DataTO newData; - public CopyCmdAnswer(Command cmd, String path) { - super(cmd); - this.path = path; + public CopyCmdAnswer(DataTO newData) { + super(null); + this.newData = newData; } - public String getPath() { - return this.path; + public DataTO getNewData() { + return this.newData; + } + + public CopyCmdAnswer(String errMsg) { + super(null, false, errMsg); } } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index fb280346793..5fe1cbed842 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -23,27 +23,13 @@ import com.cloud.agent.api.Command; public class CopyCommand extends Command implements StorageSubSystemCommand { private DataTO srcTO; private DataTO destTO; - private int timeout; - /** - * @return the timeout - */ - public int getTimeout() { - return timeout; - } - - /** - * @param timeout the timeout to set - */ - public void setTimeout(int timeout) { - this.timeout = timeout; - } public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) { super(); this.srcTO = srcUri; this.destTO = destUri; - this.timeout = timeout; + this.setWait(timeout); } public DataTO getDestTO() { diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 513a1dd1b8f..1e72ea0bdea 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -25,12 +25,15 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; import com.cloud.agent.api.to.DataStoreTO; public class TemplateObjectTO implements DataTO { - private final String path; - private final String uuid; + private String path; + private String uuid; private DiskFormat diskType; - private final ImageStoreTO imageDataStore; - private final String name; + private ImageStoreTO imageDataStore; + private String name; + public TemplateObjectTO() { + + } public TemplateObjectTO(TemplateInfo template) { this.path = template.getUri(); this.uuid = template.getUuid(); @@ -72,4 +75,13 @@ public class TemplateObjectTO implements DataTO { public String getName() { return name; } + public void setPath(String path) { + this.path = path; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + public void setName(String name) { + this.name = name; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index e556a3bd95b..1fecf68c091 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -24,13 +24,18 @@ import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; public class VolumeObjectTO implements DataTO { - private final String uuid; - private final String path; - private VolumeType volumeType; - private DiskFormat diskType; + private String uuid; + private VolumeType volumeType; + private DiskFormat diskType; private PrimaryDataStoreTO dataStore; - private String name; - private final long size; + private String name; + private long size; + private String path; + + public VolumeObjectTO() { + + } + public VolumeObjectTO(VolumeInfo volume) { this.uuid = volume.getUuid(); this.path = volume.getUri(); @@ -80,4 +85,21 @@ public class VolumeObjectTO implements DataTO { public DataObjectType getObjectType() { return DataObjectType.VOLUME; } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public void setName(String name) { + this.name = name; + } + + public void setSize(long size) { + this.size = size; + } + + public void setPath(String path) { + this.path = path; + } + } 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 index 47fe4890220..d2aacdea076 100644 --- 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 @@ -26,6 +26,7 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -116,11 +117,11 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { private class CreateCacheObjectContext extends AsyncRpcConext { - final AsyncCallFuture future; + final AsyncCallFuture future; /** * @param callback */ - public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { + public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { super(callback); this.future = future; } @@ -131,22 +132,22 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - AsyncCallFuture future = new AsyncCallFuture(); - CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallFuture future = new AsyncCallFuture(); + CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - CopyCmdAnswer result = null; + CopyCommandResult result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); dataMotionSvr.copyAsync(data, objOnCacheStore, caller); result = future.get(); - if (!result.getResult()) { + if (result.isFailed()) { cacheStore.delete(data); } else { - objOnCacheStore.processEvent(Event.OperationSuccessed, result); + objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); } } catch (InterruptedException e) { s_logger.debug("create cache storage failed: " + e.toString()); @@ -163,9 +164,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return null; } - protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, - CreateCacheObjectContext context) { - AsyncCallFuture future = context.future; + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, + CreateCacheObjectContext context) { + AsyncCallFuture future = context.future; future.complete(callback.getResult()); return null; } 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 index 8274fd75638..b0229d88640 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -317,51 +317,16 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } 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; + CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0); StoragePool pool = (StoragePool)volume.getDataStore(); - String errMsg = null; + try { - answer = storageMgr.sendToPool(pool, null, cmd); + Answer answer = storageMgr.sendToPool(pool, null, cmd); + return answer; } 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) { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 3230724ba8c..3b19a80bba5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -181,22 +181,24 @@ public class TemplateObject implements TemplateInfo { public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { if (this.getDataStore().getRole() == DataStoreRole.Primary) { - if (answer != null && answer instanceof CopyCmdAnswer) { + if (answer instanceof CopyCmdAnswer) { CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData(); VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId()); templatePoolRef.setDownloadPercent(100); templatePoolRef.setDownloadState(Status.DOWNLOADED); - templatePoolRef.setLocalDownloadPath(cpyAnswer.getPath()); - templatePoolRef.setInstallPath(cpyAnswer.getPath()); + templatePoolRef.setLocalDownloadPath(newTemplate.getPath()); + templatePoolRef.setInstallPath(newTemplate.getPath()); templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); } } else if (this.getDataStore().getRole() == DataStoreRole.Image || this.getDataStore().getRole() == DataStoreRole.ImageCache) { - if (answer != null && answer instanceof CopyCmdAnswer) { + if (answer instanceof CopyCmdAnswer) { CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData(); TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(), this.getId()); - templateStoreRef.setInstallPath(cpyAnswer.getPath()); + templateStoreRef.setInstallPath(newTemplate.getPath()); templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index c5b5883e9a3..220a7b01f6f 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -187,6 +187,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } + @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 2834ed03407..d5f5fbcf6a9 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; @@ -102,6 +103,7 @@ public class VolumeObject implements VolumeInfo { public boolean stateTransit(Volume.Event event) { boolean result = false; try { + volumeVO = volumeDao.findById(volumeVO.getId()); result = _volStateMachine.transitTo(volumeVO, event, null, volumeDao); volumeVO = volumeDao.findById(volumeVO.getId()); } catch (NoTransitionException e) { @@ -345,8 +347,18 @@ public class VolumeObject implements VolumeInfo { } @Override - public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) { - // TODO Auto-generated method stub - + public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { + if (this.dataStore.getRole() == DataStoreRole.Primary) { + if (answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; + VolumeVO vol = this.volumeDao.findById(this.getId()); + VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData(); + vol.setPath(newVol.getPath()); + vol.setSize(newVol.getSize()); + volumeDao.update(vol.getId(), vol); + } + } + + this.processEvent(event); } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 99ac50a10dd..3bf20369825 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -398,7 +398,7 @@ public class VolumeServiceImpl implements VolumeService { return null; } - templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed); + templateOnPrimaryStoreObj.processEvent(Event.OperationSuccessed, result.getAnswer()); createVolumeFromBaseImageAsync(context.volume, templateOnPrimaryStoreObj, context.dataStore, future); return null; } @@ -447,10 +447,7 @@ public class VolumeServiceImpl implements VolumeService { VolumeApiResult volResult = new VolumeApiResult(vo); if (result.isSuccess()) { - if (result.getPath() != null) { - vo.setPath(result.getPath()); - } - vo.processEvent(Event.OperationSuccessed); + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); } else { vo.processEvent(Event.OperationFailed); volResult.setResult(result.getResult()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 300daa597a2..4c25bfae0a9 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -55,15 +55,19 @@ import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.agent.api.to.VolumeTO; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.DataStoreRole; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.DecodedDataStore; import com.cloud.utils.storage.encoding.Decoder; +import com.cloud.vm.DiskProfile; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Host; import com.xensource.xenapi.PBD; @@ -548,7 +552,7 @@ public class XenServerStorageResource { //downloadHttpToLocalFile(vdiPath, template.getPath()); hypervisorResource.callHostPlugin(conn, "storagePlugin", "downloadTemplateFromUrl", "destPath", vdiPath, "srcUrl", srcObj.getPath()); result = true; - return new CopyCmdAnswer(cmd, vdi.getUuid(conn)); + //return new CopyCmdAnswer(cmd, vdi.getUuid(conn)); } catch (BadServerResponse e) { s_logger.debug("Failed to download template", e); } catch (XenAPIException e) { @@ -673,7 +677,7 @@ public class XenServerStorageResource { return parentUuid; } - protected PrimaryStorageDownloadAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { + protected CopyCmdAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { DataStoreTO srcStore = srcData.getDataStore(); try { if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) { @@ -681,7 +685,7 @@ public class XenServerStorageResource { TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData; String storeUrl = srcImageStore.getUri(); if (!storeUrl.startsWith("nfs")) { - return new PrimaryStorageDownloadAnswer("only nfs image cache store supported"); + return new CopyCmdAnswer("only nfs image cache store supported"); } String tmplpath = storeUrl + ":" + srcData.getPath(); PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore(); @@ -693,7 +697,7 @@ public class XenServerStorageResource { if (srs.size() != 1) { String msg = "There are " + srs.size() + " SRs with same name: " + poolName; s_logger.warn(msg); - return new PrimaryStorageDownloadAnswer(msg); + return new CopyCmdAnswer(msg); } else { poolsr = srs.iterator().next(); } @@ -713,66 +717,79 @@ public class XenServerStorageResource { Thread.sleep(5000); } catch (Exception e) { } - return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setUuid(snapshotvdi.getUuid(conn)); + newVol.setSize(phySize); + newVol.setPath(newVol.getUuid()); + return new CopyCmdAnswer(newVol); } }catch (Exception e) { String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString(); s_logger.warn(msg, e); - return new PrimaryStorageDownloadAnswer(msg); + return new CopyCmdAnswer(msg); + } + return new CopyCmdAnswer("not implemented yet"); + } + + protected CreateObjectAnswer createVolume(DataTO data) { + /* + VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = dskch.getName(); + vdir.SR = poolSr; + vdir.type = Types.VdiType.USER; + + vdir.virtualSize = dskch.getSize(); + vdi = VDI.create(conn, vdir); + VDI.Record vdir; + vdir = vdi.getRecord(conn); + s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid);*/ + return null; + } + protected CopyCmdAnswer cloneVolumeFromBaseTemplate(DataTO srcData, DataTO destData) { + Connection conn = hypervisorResource.getConnection(); + PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO)destData; + VDI vdi = null; + try { + VDI tmpltvdi = null; + + tmpltvdi = getVDIbyUuid(conn, srcData.getPath()); + vdi = tmpltvdi.createClone(conn, new HashMap()); + vdi.setNameLabel(conn, volume.getName()); + + + VDI.Record vdir; + vdir = vdi.getRecord(conn); + s_logger.debug("Succesfully created VDI: Uuid = " + vdir.uuid); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setName(vdir.nameLabel); + newVol.setSize(vdir.virtualSize); + newVol.setPath(vdir.uuid); + + return new CopyCmdAnswer(newVol); + } catch (Exception e) { + s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: ", e); + return new CopyCmdAnswer(e.toString()); } - return new PrimaryStorageDownloadAnswer("not implemented yet"); } protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); - - if (srcData.getObjectType() == DataObjectType.TEMPLATE && destData.getDataStore().getRole() == DataStoreRole.Primary) { + DataStoreTO srcDataStore = srcData.getDataStore(); + DataStoreTO destDataStore = destData.getDataStore(); + + if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcData.getDataStore().getRole() == DataStoreRole.ImageCache && destData.getDataStore().getRole() == DataStoreRole.Primary) { //copy template to primary storage - return copyTemplateToPrimaryStorage(srcData, destData, cmd.getTimeout()); + return copyTemplateToPrimaryStorage(srcData, destData, cmd.getWait()); + } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { + //clone template to a volume + return cloneVolumeFromBaseTemplate(srcData, destData); } - + return new Answer(cmd, false, "not implemented yet"); - /* - String tmplturl = cmd.getUrl(); - String poolName = cmd.getPoolUuid(); - int wait = cmd.getWait(); - try { - URI uri = new URI(tmplturl); - String tmplpath = uri.getHost() + ":" + uri.getPath(); - Connection conn = hypervisorResource.getConnection(); - SR poolsr = null; - Set srs = SR.getByNameLabel(conn, poolName); - if (srs.size() != 1) { - String msg = "There are " + srs.size() + " SRs with same name: " + poolName; - s_logger.warn(msg); - return new PrimaryStorageDownloadAnswer(msg); - } else { - poolsr = srs.iterator().next(); - } - String pUuid = poolsr.getUuid(conn); - boolean isISCSI = IsISCSI(poolsr.getType(conn)); - String uuid = copy_vhd_from_secondarystorage(conn, tmplpath, pUuid, wait); - VDI tmpl = getVDIbyUuid(conn, uuid); - VDI snapshotvdi = tmpl.snapshot(conn, new HashMap()); - String snapshotUuid = snapshotvdi.getUuid(conn); - snapshotvdi.setNameLabel(conn, "Template " + cmd.getName()); - String parentuuid = getVhdParent(conn, pUuid, snapshotUuid, isISCSI); - VDI parent = getVDIbyUuid(conn, parentuuid); - Long phySize = parent.getPhysicalUtilisation(conn); - tmpl.destroy(conn); - poolsr.scan(conn); - try{ - Thread.sleep(5000); - } catch (Exception e) { - } - return new PrimaryStorageDownloadAnswer(snapshotvdi.getUuid(conn), phySize); - } catch (Exception e) { - String msg = "Catch Exception " + e.getClass().getName() + " on host:" + _host.uuid + " for template: " - + tmplturl + " due to " + e.toString(); - s_logger.warn(msg, e); - return new PrimaryStorageDownloadAnswer(msg); - }*/ - } + } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index d9113b47eec..4debdc3b73f 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -175,7 +175,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - caller.setCallback(this.createAsyncCallback(null, null)); + caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; From e40a06deaea3c040255d8472ea3c9301f8fb2955 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 22 Apr 2013 21:48:57 -0700 Subject: [PATCH 050/303] Fix extractTemplateCmd. --- .../cloud/template/TemplateApiService.java | 5 +- .../cloudstack/api/ResponseGenerator.java | 2 +- .../api/command/user/iso/ExtractIsoCmd.java | 14 +- .../user/template/ExtractTemplateCmd.java | 14 +- .../subsystem/api/storage/EndPoint.java | 1 + .../image/datastore/ImageStoreEntity.java | 0 .../cloudstack/storage/LocalHostEndpoint.java | 10 +- .../storage/RemoteHostEndPoint.java | 17 +- .../src/com/cloud/api/ApiResponseHelper.java | 19 +- .../cloud/storage/upload/UploadMonitor.java | 10 +- .../storage/upload/UploadMonitorImpl.java | 196 +++++++++--------- .../cloud/template/TemplateManagerImpl.java | 80 +++---- 12 files changed, 200 insertions(+), 168 deletions(-) rename engine/{storage => api}/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java (100%) diff --git a/api/src/com/cloud/template/TemplateApiService.java b/api/src/com/cloud/template/TemplateApiService.java index e3906e10d83..d907b103ed4 100755 --- a/api/src/com/cloud/template/TemplateApiService.java +++ b/api/src/com/cloud/template/TemplateApiService.java @@ -36,6 +36,7 @@ import com.cloud.exception.InternalErrorException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; import com.cloud.user.Account; +import com.cloud.utils.Pair; import com.cloud.utils.exception.CloudRuntimeException; public interface TemplateApiService { @@ -76,7 +77,7 @@ public interface TemplateApiService { * - the command specifying the mode and id of the ISO * @return extractId. */ - Long extract(ExtractIsoCmd cmd) throws InternalErrorException; + Pair extract(ExtractIsoCmd cmd) throws InternalErrorException; /** * Extracts a Template @@ -85,7 +86,7 @@ public interface TemplateApiService { * - the command specifying the mode and id of the template * @return extractId */ - Long extract(ExtractTemplateCmd cmd) throws InternalErrorException; + Pair extract(ExtractTemplateCmd cmd) throws InternalErrorException; VirtualMachineTemplate getTemplate(long templateId); diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 77d3bea59cd..c780bda6c17 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -257,7 +257,7 @@ public interface ResponseGenerator { SecurityGroupResponse createSecurityGroupResponse(SecurityGroup group); - ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode); + ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url); String toSerializedString(CreateCmdResponse response, String responseType); diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java index 08a15eece73..c405f2d6e91 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java @@ -33,6 +33,7 @@ import com.cloud.exception.InternalErrorException; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.UserContext; +import com.cloud.utils.Pair; @APICommand(name = "extractIso", description="Extracts an ISO", responseObject=ExtractResponse.class) public class ExtractIsoCmd extends BaseAsyncCmd { @@ -123,9 +124,16 @@ public class ExtractIsoCmd extends BaseAsyncCmd { public void execute(){ try { UserContext.current().setEventDetails(getEventDescription()); - Long uploadId = _templateService.extract(this); - if (uploadId != null){ - ExtractResponse response = _responseGenerator.createExtractResponse(uploadId, id, zoneId, getEntityOwnerId(), mode); + Pair uploadPair = _templateService.extract(this); + if (uploadPair != null){ + ExtractResponse response = null; + if (uploadPair.second() != null ) { + // region-wide image store + response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second()); + } else { + // nfs image store + response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null); + } response.setResponseName(getCommandName()); response.setObjectName("iso"); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java index 9a2dee30bcb..2ec957ebe86 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java @@ -34,6 +34,7 @@ import com.cloud.exception.InternalErrorException; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.UserContext; +import com.cloud.utils.Pair; @APICommand(name = "extractTemplate", description="Extracts a template", responseObject=ExtractResponse.class) public class ExtractTemplateCmd extends BaseAsyncCmd { @@ -125,9 +126,16 @@ public class ExtractTemplateCmd extends BaseAsyncCmd { public void execute(){ try { UserContext.current().setEventDetails(getEventDescription()); - Long uploadId = _templateService.extract(this); - if (uploadId != null){ - ExtractResponse response = _responseGenerator.createExtractResponse(uploadId, id, zoneId, getEntityOwnerId(), mode); + Pair uploadPair = _templateService.extract(this); + if (uploadPair != null){ + ExtractResponse response = null; + if (uploadPair.second() != null ) { + // region-wide image store + response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second()); + } else { + // nfs image store + response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null); + } response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java index eb6da701208..4966419dc3e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java @@ -24,6 +24,7 @@ import com.cloud.agent.api.Command; public interface EndPoint { public long getId(); + public String getHostAddr(); public Answer sendMessage(Command cmd); public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); void sendMessageAsyncWithListener(Command cmd, Listener listner); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java similarity index 100% rename from engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java rename to engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 9fe0c552850..8844b4cce9e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -30,7 +30,13 @@ public class LocalHostEndpoint implements EndPoint { return 0; } + @Override + public String getHostAddr() { + return "127.0.0.0"; + } + + @Override public Answer sendMessage(Command cmd) { if (cmd instanceof CopyCommand) { return resource.executeRequest(cmd); @@ -52,7 +58,7 @@ public class LocalHostEndpoint implements EndPoint { callback.complete(answer); } } - + private class CmdRunner2 implements Runnable { final Command cmd; final AsyncCompletionCallback callback; @@ -71,7 +77,7 @@ public class LocalHostEndpoint implements EndPoint { AsyncCompletionCallback callback) { executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); } - + @Override public void sendMessageAsyncWithListener(Command cmd, Listener listner) { if (listner instanceof DownloadListener) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 9ce4e759fc9..acf78f24a89 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -51,22 +51,23 @@ public class RemoteHostEndPoint implements EndPoint { protected RemoteHostEndPoint() { executor = Executors.newScheduledThreadPool(10); } - + private void configure(long hostId, String hostAddress) { this.hostId = hostId; this.hostAddress = hostAddress; } - + public static RemoteHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress) { RemoteHostEndPoint ep = ComponentContext.inject(RemoteHostEndPoint.class); ep.configure(hostId, hostAddress); return ep; } - + + @Override public String getHostAddr() { return this.hostAddress; } - + public long getId() { return this.hostId; } @@ -85,7 +86,7 @@ public class RemoteHostEndPoint implements EndPoint { } throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg); } - + private class CmdRunner implements Runnable { final Command cmd; final AsyncCompletionCallback callback; @@ -98,14 +99,14 @@ public class RemoteHostEndPoint implements EndPoint { Answer answer = sendMessage(cmd); callback.complete(answer); } - + } - + @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); } - + @Override public void sendMessageAsyncWithListener(Command cmd, Listener listener) { try { diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index a0c9d38cd24..faf61555d47 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -242,6 +242,7 @@ import com.cloud.storage.ImageStore; import com.cloud.storage.S3; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Upload; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; @@ -1525,8 +1526,8 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode) { - UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId); + public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) { + ExtractResponse response = new ExtractResponse(); response.setObjectName("template"); VMTemplateVO template = ApiDBUtils.findTemplateById(id); @@ -1538,11 +1539,19 @@ public class ApiResponseHelper implements ResponseGenerator { response.setZoneName(zone.getName()); } response.setMode(mode); - response.setUploadId(uploadInfo.getUuid()); - response.setState(uploadInfo.getUploadState().toString()); + if (uploadId == null) { + // region-wide image store + response.setUrl(url); + response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString()); + } else { + UploadVO uploadInfo = ApiDBUtils.findUploadById(uploadId); + response.setUploadId(uploadInfo.getUuid()); + response.setState(uploadInfo.getUploadState().toString()); + response.setUrl(uploadInfo.getUploadUrl()); + } Account account = ApiDBUtils.findAccountById(accountId); response.setAccountId(account.getUuid()); - response.setUrl(uploadInfo.getUploadUrl()); + return response; } diff --git a/server/src/com/cloud/storage/upload/UploadMonitor.java b/server/src/com/cloud/storage/upload/UploadMonitor.java index 1c3590e91e2..dd50d1ae40f 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitor.java +++ b/server/src/com/cloud/storage/upload/UploadMonitor.java @@ -17,6 +17,8 @@ package com.cloud.storage.upload; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; + import com.cloud.async.AsyncJobManager; import com.cloud.host.HostVO; import com.cloud.storage.Upload.Mode; @@ -32,12 +34,12 @@ import com.cloud.utils.component.Manager; * Monitor upload progress of all entities. * */ -public interface UploadMonitor extends Manager{ - +public interface UploadMonitor extends Manager{ + public void cancelAllUploads(Long templateId); public Long extractTemplate(VMTemplateVO template, String url, - VMTemplateHostVO tmpltHostRef,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr); + TemplateDataStoreVO tmpltStoreRef,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr); boolean isTypeUploadInProgress(Long typeId, Type type); @@ -51,7 +53,7 @@ public interface UploadMonitor extends Manager{ long asyncJobId, AsyncJobManager asyncMgr); UploadVO createEntityDownloadURL(VMTemplateVO template, - VMTemplateHostVO vmTemplateHost, Long dataCenterId, long eventId); + TemplateDataStoreVO vmTemplateStore, Long dataCenterId, long eventId); void createVolumeDownloadURL(Long entityId, String path, Type type, Long dataCenterId, Long uploadId); diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 77f0d209918..0495255a84c 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -32,14 +32,22 @@ import javax.ejb.Local; 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.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; +import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; +import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.manager.Commands; @@ -56,6 +64,7 @@ import com.cloud.storage.Upload; import com.cloud.storage.Upload.Mode; import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Type; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateVO; @@ -82,17 +91,17 @@ import com.cloud.vm.dao.SecondaryStorageVmDao; public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { static final Logger s_logger = Logger.getLogger(UploadMonitorImpl.class); - - @Inject + + @Inject VMTemplateHostDao _vmTemplateHostDao; - @Inject + @Inject UploadDao _uploadDao; @Inject SecondaryStorageVmDao _secStorageVmDao; - + @Inject - HostDao _serverDao = null; + HostDao _serverDao = null; @Inject VMTemplateDao _templateDao = null; @Inject @@ -103,6 +112,10 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { ResourceManager _resourceMgr; @Inject SecondaryStorageVmManager _ssvmMgr; + @Inject + EndPointSelector _epSelector; + @Inject + DataStoreManager storeMgr; private String _name; private Boolean _sslCopy = new Boolean(false); @@ -114,46 +127,46 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { final Map _listenerMap = new ConcurrentHashMap(); - + @Override public void cancelAllUploads(Long templateId) { // TODO - } - + } + @Override public boolean isTypeUploadInProgress(Long typeId, Type type) { List uploadsInProgress = _uploadDao.listByTypeUploadStatus(typeId, type, UploadVO.Status.UPLOAD_IN_PROGRESS); - + if(uploadsInProgress.size() > 0) { return true; } else if (type == Type.VOLUME && _uploadDao.listByTypeUploadStatus(typeId, type, UploadVO.Status.COPY_IN_PROGRESS).size() > 0){ return true; } return false; - + } - + @Override public UploadVO createNewUploadEntry(Long hostId, Long typeId, UploadVO.Status uploadState, Type type, String uploadUrl, Upload.Mode mode){ - - UploadVO uploadObj = new UploadVO(hostId, typeId, new Date(), + + UploadVO uploadObj = new UploadVO(hostId, typeId, new Date(), uploadState, type, uploadUrl, mode); _uploadDao.persist(uploadObj); - + return uploadObj; - + } - + @Override - public void extractVolume(UploadVO uploadVolumeObj, HostVO sserver, VolumeVO volume, String url, Long dataCenterId, String installPath, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ - + public void extractVolume(UploadVO uploadVolumeObj, HostVO sserver, VolumeVO volume, String url, Long dataCenterId, String installPath, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ + uploadVolumeObj.setUploadState(Upload.Status.NOT_UPLOADED); _uploadDao.update(uploadVolumeObj.getId(), uploadVolumeObj); - - start(); + + start(); UploadCommand ucmd = new UploadCommand(url, volume.getId(), volume.getSize(), installPath, Type.VOLUME); UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadVolumeObj, this, ucmd, volume.getAccountId(), volume.getName(), Type.VOLUME, eventId, asyncJobId, asyncMgr); _listenerMap.put(uploadVolumeObj, ul); @@ -164,26 +177,26 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { s_logger.warn("Unable to start upload of volume " + volume.getName() + " from " + sserver.getName() + " to " +url, e); ul.setDisconnected(); ul.scheduleStatusCheck(RequestType.GET_OR_RESTART); - } + } } @Override public Long extractTemplate( VMTemplateVO template, String url, - VMTemplateHostVO vmTemplateHost,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ + TemplateDataStoreVO vmTemplateHost,Long dataCenterId, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; - + List storageServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.SecondaryStorage, dataCenterId); - HostVO sserver = storageServers.get(0); - - UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), template.getId(), new Date(), + HostVO sserver = storageServers.get(0); + + UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), template.getId(), new Date(), Upload.Status.NOT_UPLOADED, type, url, Mode.FTP_UPLOAD); - _uploadDao.persist(uploadTemplateObj); - + _uploadDao.persist(uploadTemplateObj); + if(vmTemplateHost != null) { start(); - UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost.getInstallPath(), vmTemplateHost.getSize()); - UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), template.getName(), type, eventId, asyncJobId, asyncMgr); + UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost.getInstallPath(), vmTemplateHost.getSize()); + UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), template.getName(), type, eventId, asyncJobId, asyncMgr); _listenerMap.put(uploadTemplateObj, ul); try { @@ -194,57 +207,54 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { ul.scheduleStatusCheck(RequestType.GET_OR_RESTART); } return uploadTemplateObj.getId(); - } - return null; - } - + } + return null; + } + @Override - public UploadVO createEntityDownloadURL(VMTemplateVO template, VMTemplateHostVO vmTemplateHost, Long dataCenterId, long eventId) { - + public UploadVO createEntityDownloadURL(VMTemplateVO template, TemplateDataStoreVO vmTemplateHost, Long dataCenterId, long eventId) { + String errorString = ""; boolean success = false; - Host secStorage = ApiDBUtils.findHostById(vmTemplateHost.getHostId()); Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; - - //Check if ssvm is up - HostVO ssvm = _ssvmMgr.pickSsvmHost(ApiDBUtils.findHostById(vmTemplateHost.getHostId())); - if( ssvm == null ) { - throw new CloudRuntimeException("There is no secondary storage VM for secondary storage host " + secStorage.getId()); - } - + + //Check if it already exists. - List extractURLList = _uploadDao.listByTypeUploadStatus(template.getId(), type, UploadVO.Status.DOWNLOAD_URL_CREATED); + List extractURLList = _uploadDao.listByTypeUploadStatus(template.getId(), type, UploadVO.Status.DOWNLOAD_URL_CREATED); if (extractURLList.size() > 0) { return extractURLList.get(0); } - - // It doesn't exist so create a DB entry. - UploadVO uploadTemplateObj = new UploadVO(vmTemplateHost.getHostId(), template.getId(), new Date(), - Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD); - uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath()); + + // It doesn't exist so create a DB entry. + UploadVO uploadTemplateObj = new UploadVO(vmTemplateHost.getDataStoreId(), template.getId(), new Date(), + Status.DOWNLOAD_URL_NOT_CREATED, 0, type, Mode.HTTP_DOWNLOAD); + uploadTemplateObj.setInstallPath(vmTemplateHost.getInstallPath()); _uploadDao.persist(uploadTemplateObj); + + // find an endpoint to send command + DataStore store = this.storeMgr.getDataStore(vmTemplateHost.getDataStoreId(), DataStoreRole.Image); + EndPoint ep = _epSelector.select(store); try{ // Create Symlink at ssvm String path = vmTemplateHost.getInstallPath(); String uuid = UUID.randomUUID().toString() + "." + template.getFormat().getFileExtension(); // adding "." + vhd/ova... etc. - CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(secStorage.getParent(), path, uuid); - try { - send(ssvm.getId(), cmd, null); - } catch (AgentUnavailableException e) { - errorString = "Unable to create a link for " +type+ " id:"+template.getId() + "," + e.getMessage(); - s_logger.error(errorString, e); + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreVO)store).getParent(), path, uuid); + Answer ans = ep.sendMessage(cmd); + if (ans == null || !ans.getResult()) { + errorString = "Unable to create a link for " +type+ " id:"+template.getId() + "," + ans.getDetails(); + s_logger.error(errorString); throw new CloudRuntimeException(errorString); } //Construct actual URL locally now that the symlink exists at SSVM - String extractURL = generateCopyUrl(ssvm.getPublicIpAddress(), uuid); + String extractURL = generateCopyUrl(ep.getHostAddr(), uuid); UploadVO vo = _uploadDao.createForUpdate(); vo.setLastUpdated(new Date()); vo.setUploadUrl(extractURL); vo.setUploadState(Status.DOWNLOAD_URL_CREATED); _uploadDao.update(uploadTemplateObj.getId(), vo); success = true; - return _uploadDao.findById(uploadTemplateObj.getId(), true); + return _uploadDao.findById(uploadTemplateObj.getId(), true); }finally{ if(!success){ UploadVO uploadJob = _uploadDao.createForUpdate(uploadTemplateObj.getId()); @@ -254,22 +264,22 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { _uploadDao.update(uploadTemplateObj.getId(), uploadJob); } } - + } - + @Override public void createVolumeDownloadURL(Long entityId, String path, Type type, Long dataCenterId, Long uploadId) { - + String errorString = ""; boolean success = false; try{ List storageServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.SecondaryStorage, dataCenterId); if(storageServers == null ){ errorString = "No Storage Server found at the datacenter - " +dataCenterId; - throw new CloudRuntimeException(errorString); - } - - // Update DB for state = DOWNLOAD_URL_NOT_CREATED. + throw new CloudRuntimeException(errorString); + } + + // Update DB for state = DOWNLOAD_URL_NOT_CREATED. UploadVO uploadJob = _uploadDao.createForUpdate(uploadId); uploadJob.setUploadState(Status.DOWNLOAD_URL_NOT_CREATED); uploadJob.setLastUpdated(new Date()); @@ -283,7 +293,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { errorString = "There is no secondary storage VM for secondary storage host " + secStorage.getName(); throw new CloudRuntimeException(errorString); } - + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(secStorage.getParent(), path, uuid); try { send(ssvm.getId(), cmd, null); @@ -323,7 +333,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } } } - + private String generateCopyUrl(String ipAddress, String uuid){ String hostname = ipAddress; String scheme = "http"; @@ -332,9 +342,9 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { hostname = hostname + ".realhostip.com"; scheme = "https"; } - return scheme + "://" + hostname + "/userdata/" + uuid; + return scheme + "://" + hostname + "/userdata/" + uuid; } - + public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException { @@ -346,19 +356,19 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { throws ConfigurationException { final Map configs = _configDao.getConfiguration("ManagementServer", params); _sslCopy = Boolean.parseBoolean(configs.get("secstorage.encrypt.copy")); - + String cert = configs.get("secstorage.secure.copy.cert"); if ("realhostip.com".equalsIgnoreCase(cert)) { s_logger.warn("Only realhostip.com ssl cert is supported, ignoring self-signed and other certs"); - } - + } + _agentMgr.registerForHostEvents(new UploadListener(this), true, false, false); String cleanupInterval = configs.get("extract.url.cleanup.interval"); _cleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200); - + String urlExpirationInterval = configs.get("extract.url.expiration.interval"); _urlExpirationInterval = NumbersUtil.parseInt(urlExpirationInterval, 14400); - + String workers = (String)params.get("expunge.workers"); int wrks = NumbersUtil.parseInt(workers, 1); _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UploadMonitor-Scavenger")); @@ -366,19 +376,19 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } @Override - public boolean start() { + public boolean start() { _executor.scheduleWithFixedDelay(new StorageGarbageCollector(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS); _timer = new Timer(); return true; } @Override - public boolean stop() { + public boolean stop() { return true; } - + public void handleUploadEvent(HostVO host, Long accountId, String typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason, long eventId) { - + if ((reason == Upload.Status.UPLOADED) || (reason==Upload.Status.ABANDONED)){ UploadVO uploadObj = new UploadVO(uploadId); UploadListener oldListener = _listenerMap.get(uploadObj); @@ -388,10 +398,10 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } } - + @Override public void handleUploadSync(long sserverId) { - + HostVO storageHost = _serverDao.findById(sserverId); if (storageHost == null) { s_logger.warn("Huh? Agent id " + sserverId + " does not correspond to a row in hosts table?"); @@ -408,11 +418,11 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { uploadJob.setLastUpdated(new Date()); _uploadDao.update(uploadJob.getId(), uploadJob); } - - } - - } + } + + + } protected class StorageGarbageCollector implements Runnable { @@ -440,26 +450,26 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } } } - - + + private long getTimeDiff(Date date){ Calendar currentDateCalendar = Calendar.getInstance(); Calendar givenDateCalendar = Calendar.getInstance(); givenDateCalendar.setTime(date); - - return (currentDateCalendar.getTimeInMillis() - givenDateCalendar.getTimeInMillis() )/1000; + + return (currentDateCalendar.getTimeInMillis() - givenDateCalendar.getTimeInMillis() )/1000; } - + public void cleanupStorage() { final int EXTRACT_URL_LIFE_LIMIT_IN_SECONDS = _urlExpirationInterval; List extractJobs= _uploadDao.listByModeAndStatus(Mode.HTTP_DOWNLOAD, Status.DOWNLOAD_URL_CREATED); - + for (UploadVO extractJob : extractJobs){ - if( getTimeDiff(extractJob.getLastUpdated()) > EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){ + if( getTimeDiff(extractJob.getLastUpdated()) > EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){ String path = extractJob.getInstallPath(); HostVO secStorage = ApiDBUtils.findHostById(extractJob.getHostId()); - + // Would delete the symlink for the Type and if Type == VOLUME then also the volume DeleteEntityDownloadURLCommand cmd = new DeleteEntityDownloadURLCommand(path, extractJob.getType(),extractJob.getUploadUrl(), secStorage.getParent()); HostVO ssvm = _ssvmMgr.pickSsvmHost(secStorage); @@ -478,7 +488,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } } } - + } } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 02669958081..81cf29c0b0d 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -67,7 +67,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -78,6 +77,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -88,8 +88,6 @@ import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand; import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.SwiftTO; import com.cloud.api.ApiDBUtils; @@ -353,7 +351,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true) - public Long extract(ExtractIsoCmd cmd) { + public Pair extract(ExtractIsoCmd cmd) { Account account = UserContext.current().getCaller(); Long templateId = cmd.getId(); Long zoneId = cmd.getZoneId(); @@ -362,9 +360,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Long eventId = cmd.getStartEventId(); // FIXME: async job needs fixing - Long uploadId = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr); - if (uploadId != null){ - return uploadId; + Pair uploadPair = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr); + if (uploadPair != null){ + return uploadPair; }else { throw new CloudRuntimeException("Failed to extract the iso"); } @@ -372,7 +370,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true) - public Long extract(ExtractTemplateCmd cmd) { + public Pair extract(ExtractTemplateCmd cmd) { Account caller = UserContext.current().getCaller(); Long templateId = cmd.getId(); Long zoneId = cmd.getZoneId(); @@ -381,9 +379,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Long eventId = cmd.getStartEventId(); // FIXME: async job needs fixing - Long uploadId = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr); - if (uploadId != null){ - return uploadId; + Pair uploadPair = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr); + if (uploadPair != null){ + return uploadPair; }else { throw new CloudRuntimeException("Failed to extract the teamplate"); } @@ -402,7 +400,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return vmTemplate; } - private Long extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) { + private Pair extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) { String desc = Upload.Type.TEMPLATE.toString(); if (isISO) { desc = Upload.Type.ISO.toString(); @@ -434,15 +432,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - if (zoneId == null && _swiftMgr.isSwiftEnabled()) { - zoneId = _swiftMgr.chooseZoneForTmpltExtract(templateId); - } - if (zoneId == null && _s3Mgr.isS3Enabled()) { - zoneId = _s3Mgr.chooseZoneForTemplateExtract(template); - } - - if (_dcDao.findById(zoneId) == null) { + if (zoneId != null && _dcDao.findById(zoneId) == null) { throw new IllegalArgumentException("Please specify a valid zone."); } @@ -452,39 +443,33 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - List sservers = getSecondaryStorageHosts(zoneId); + List ssStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); - VMTemplateHostVO tmpltHostRef = null; - if (sservers != null) { - for(HostVO secondaryStorageHost: sservers){ - tmpltHostRef = _tmpltHostDao.findByHostTemplate(secondaryStorageHost.getId(), templateId); - if (tmpltHostRef != null){ - if (tmpltHostRef.getDownloadState() != com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - tmpltHostRef = null; - } - else { + TemplateDataStoreVO tmpltStoreRef = null; + ImageStoreEntity tmpltStore = null; + if (ssStores != null) { + for(DataStore store: ssStores){ + tmpltStoreRef = this._tmplStoreDao.findByStoreTemplate(store.getId(), templateId); + if (tmpltStoreRef != null){ + if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + tmpltStore = (ImageStoreEntity)store; break; } } } } - if (tmpltHostRef == null && _swiftMgr.isSwiftEnabled()) { - SwiftTO swift = _swiftMgr.getSwiftTO(templateId); - if (swift != null && sservers != null) { - downloadTemplateFromSwiftToSecondaryStorage(zoneId, templateId); - } - } else if (tmpltHostRef == null && _s3Mgr.isS3Enabled()) { - if (sservers != null) { - _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(zoneId, - templateId, _primaryStorageDownloadWait); - } - } - - if (tmpltHostRef == null) { + if (tmpltStoreRef == null) { throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); } + if ( tmpltStore.getProviderName().equalsIgnoreCase("S3") || tmpltStore.getProviderName().equalsIgnoreCase("Swift")){ + // for S3 and Swift, no need to do anything, just return template url for extract template, here we use "-1" to indicate these case + return new Pair(null, tmpltStoreRef.getInstallPath()); + } + + + // for NFS image store case, control will come here Upload.Mode extractMode; if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){ throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD); @@ -520,12 +505,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same"); } - return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr); + return new Pair(_uploadMonitor.extractTemplate(template, url, tmpltStoreRef, zoneId, eventId, job.getId(), mgr), null); } - UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltHostRef, zoneId, eventId); + UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltStoreRef, zoneId, eventId); if (vo != null){ - return vo.getId(); + return new Pair(vo.getId(), null); }else{ return null; } @@ -537,7 +522,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if(pool.getDataCenterId() == zoneId) { s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); this._preloadExecutor.execute(new Runnable() { - public void run() { + @Override + public void run() { try { reallyRun(); } catch(Throwable e) { From 4cd3903c9d289e7653b60b67759fa67ffa8b729b Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 23 Apr 2013 10:41:09 -0700 Subject: [PATCH 051/303] change iszoneready, to use imagestore table --- .../SecondaryStorageManagerImpl.java | 47 +++++++++---------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 7f729c3563d..7aa4efb23c3 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -115,6 +115,7 @@ import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; +import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountService; import com.cloud.user.User; @@ -241,6 +242,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar protected IPAddressDao _ipAddressDao = null; @Inject protected RulesManager _rulesMgr; + @Inject + TemplateManager templateMgr; @Inject KeystoreManager _keystoreMgr; @@ -739,41 +742,35 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId); if (zoneHostInfo != null && (zoneHostInfo.getFlags() & RunningHostInfoAgregator.ZoneHostInfo.ROUTING_HOST_MASK) != 0) { VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId); - HostVO secHost = _ssvmMgr.findSecondaryStorageHost(dataCenterId); - if (secHost == null) { + if (template == null) { + s_logger.debug("No hypervisor host added in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm"); + return false; + } + + List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId)); + if (stores.size() < 1) { + s_logger.debug("No image store added in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm"); + return false; + } + + DataStore store = templateMgr.getImageStore(dataCenterId, template.getId()); + if (store == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("No secondary storage available in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm"); } return false; } - boolean templateReady = false; - if (template != null) { - VMTemplateHostVO templateHostRef = _vmTemplateHostDao.findByHostTemplate(secHost.getId(), template.getId()); - templateReady = (templateHostRef != null) && (templateHostRef.getDownloadState() == Status.DOWNLOADED); - } - - if (templateReady) { - - List> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage); - if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) { - - return true; - } else { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId + " system.vm.use.local.storage: " + _useLocalStorage + - "If you want to use local storage to start ssvm, need to set system.vm.use.local.storage to true"); - } - } + List> l = _storagePoolHostDao.getDatacenterStoragePoolHostInfo(dataCenterId, !_useLocalStorage); + if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) { + return true; } else { if (s_logger.isDebugEnabled()) { - if (template == null) { - s_logger.debug("Zone host is ready, but secondary storage vm template does not exist"); - } else { - s_logger.debug("Zone host is ready, but secondary storage vm template: " + template.getId() + " is not ready on secondary storage: " + secHost.getId()); - } + s_logger.debug("Primary storage is not ready, wait until it is ready to launch secondary storage vm. dcId: " + dataCenterId + " system.vm.use.local.storage: " + _useLocalStorage + + "If you want to use local storage to start ssvm, need to set system.vm.use.local.storage to true"); } } + } return false; } From 06b30920837805053b76c84aaf817e1efd1d20f7 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 23 Apr 2013 12:10:40 -0700 Subject: [PATCH 052/303] Remove VMTemplateHostDao reference from VolumeManagerImpl, StorageManagerImpl and SecondaryStorageManagerImpl. --- .../datastore/db/TemplateDataStoreDao.java | 8 +- .../image/db/TemplateDataStoreDaoImpl.java | 46 ++++- .../com/cloud/storage/StorageManagerImpl.java | 25 +-- .../com/cloud/storage/VolumeManagerImpl.java | 166 ++++++++---------- .../SecondaryStorageManagerImpl.java | 35 ++-- .../secondary/SecondaryStorageVmManager.java | 2 +- 6 files changed, 135 insertions(+), 147 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index e9485267174..f08f76d8b0f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -23,7 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; @@ -40,7 +40,11 @@ public interface TemplateDataStoreDao extends GenericDao listByTemplateStoreStatus(long templateId, long storeId, State... states); - List listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status); + List listByTemplateStoreDownloadStatus(long templateId, long storeId, VMTemplateStorageResourceAssoc.Status... status); + + List listByTemplateZoneDownloadStatus(long templateId, Long zoneId, VMTemplateStorageResourceAssoc.Status... status); + + TemplateDataStoreVO findByTemplateZoneDownloadStatus(long templateId, Long zoneId, VMTemplateStorageResourceAssoc.Status... status); TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index eccb02aff4e..aa84821325a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -15,21 +15,26 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.image.db; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +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.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.storage.VMTemplateHostVO; + import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; @@ -38,6 +43,8 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; +import edu.emory.mathcs.backport.java.util.Collections; + @Component public class TemplateDataStoreDaoImpl extends GenericDaoBase implements TemplateDataStoreDao { private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class); @@ -49,6 +56,8 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase storeTemplateDownloadStatusSearch; + @Inject private DataStoreManager _storeMgr; + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); @@ -197,6 +206,41 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase listByTemplateZoneDownloadStatus(long templateId, Long zoneId, Status... status) { + // get all elgible image stores + List imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); + if ( imgStores != null ){ + List result = new ArrayList(); + for (DataStore store : imgStores){ + List sRes = this.listByTemplateStoreDownloadStatus(templateId, store.getId(), status); + if ( sRes != null && sRes.size() > 0){ + result.addAll(sRes); + } + } + return result; + } + return null; + } + + + @Override + public TemplateDataStoreVO findByTemplateZoneDownloadStatus(long templateId, Long zoneId, Status... status) { + // get all elgible image stores + List imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); + if ( imgStores != null ){ + for (DataStore store : imgStores){ + List sRes = this.listByTemplateStoreDownloadStatus(templateId, store.getId(), status); + if ( sRes != null && sRes.size() > 0){ + Collections.shuffle(sRes); + return sRes.get(0); + } + } + } + return null; + } + @Override public TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId) { SearchCriteria sc = storeTemplateSearch.create(); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 1a59f66f329..b91c87ec6ab 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -84,18 +84,14 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.CleanupSnapshotBackupCommand; import com.cloud.agent.api.Command; -import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.manager.AgentAttache; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; -import com.cloud.async.AsyncJobManager; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityManager; import com.cloud.capacity.CapacityState; @@ -106,7 +102,6 @@ import com.cloud.cluster.ManagementServerHostVO; import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; @@ -134,12 +129,9 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; -import com.cloud.network.NetworkModel; import com.cloud.org.Grouping; import com.cloud.org.Grouping.AllocationState; -import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; -import com.cloud.resource.ResourceStateAdapter; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; import com.cloud.service.dao.ServiceOfferingDao; @@ -152,25 +144,20 @@ import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolWorkDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateS3Dao; import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; -import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.listener.VolumeStateListener; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.snapshot.SnapshotScheduler; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.user.dao.AccountDao; @@ -191,17 +178,13 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.DiskProfile; import com.cloud.vm.UserVmManager; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfileImpl; import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @@ -238,8 +221,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected AlertManager _alertMgr; @Inject - protected VMTemplateHostDao _vmTemplateHostDao = null; - @Inject protected VMTemplatePoolDao _vmTemplatePoolDao = null; @Inject protected VMTemplateSwiftDao _vmTemplateSwiftDao = null; @@ -286,8 +267,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected VMTemplateDao _templateDao; @Inject - protected VMTemplateHostDao _templateHostDao; - @Inject protected ServiceOfferingDao _offeringDao; @Inject protected DomainDao _domainDao; @@ -1291,14 +1270,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C + ((answer == null) ? "answer is null" : answer.getDetails())); } else { - _vmTemplateHostDao + _templateStoreDao .remove(destroyedTemplateStoreVO.getId()); s_logger.debug("Deleted template at: " + destroyedTemplateStoreVO .getInstallPath()); } } else { - _vmTemplateHostDao.remove(destroyedTemplateStoreVO + _templateStoreDao.remove(destroyedTemplateStoreVO .getId()); } } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 4a7a1409ae6..dcad55b2b45 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -59,6 +59,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeAp import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -215,7 +217,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @Inject protected AlertManager _alertMgr; @Inject - protected VMTemplateHostDao _vmTemplateHostDao = null; + protected TemplateDataStoreDao _vmTemplateStoreDao = null; @Inject protected VMTemplatePoolDao _vmTemplatePoolDao = null; @Inject @@ -253,8 +255,6 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @Inject protected VMTemplateDao _templateDao; @Inject - protected VMTemplateHostDao _templateHostDao; - @Inject protected ServiceOfferingDao _offeringDao; @Inject protected DomainDao _domainDao; @@ -318,12 +318,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { private int _customDiskOfferingMaxSize = 1024; private long _maxVolumeSizeInGb; private boolean _recreateSystemVmEnabled; - protected SearchBuilder HostTemplateStatesSearch; - + public VolumeManagerImpl() { _volStateMachine = Volume.State.getStateMachine(); } - + @Override public VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId, Long destPoolPodId, Long destPoolClusterId, @@ -341,7 +340,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { dskCh.setHyperType(dataDiskHyperType); DataCenterVO destPoolDataCenter = _dcDao.findById(destPoolDcId); HostPodVO destPoolPod = _podDao.findById(destPoolPodId); - + StoragePool destPool = storageMgr.findStoragePool(dskCh, destPoolDataCenter, destPoolPod, destPoolClusterId, null, null, new HashSet()); @@ -350,7 +349,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new CloudRuntimeException( "Failed to find a storage pool with enough capacity to move the volume to."); } - + Volume newVol = migrateVolume(volume, destPool); return this.volFactory.getVolume(newVol.getId()); } @@ -373,16 +372,16 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { DataStore store = this._tmpltMgr.getImageStore(imageStoreUuid, zoneId); validateVolume(caller, ownerId, zoneId, volumeName, url, format); - + VolumeVO volume = persistVolume(caller, ownerId, zoneId, volumeName, url, cmd.getFormat()); - + VolumeInfo vol = this.volFactory.getVolume(volume.getId()); - + RegisterVolumePayload payload = new RegisterVolumePayload(cmd.getUrl(), cmd.getChecksum(), cmd.getFormat()); vol.addPayload(payload); - + this.volService.registerVolume(vol, store); return volume; } @@ -478,7 +477,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return false; } - + @Override public VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId) { VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(), @@ -495,7 +494,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { newVol.setRecreatable(oldVol.isRecreatable()); return _volsDao.persist(newVol); } - + @DB protected VolumeInfo createVolumeFromSnapshot(VolumeVO volume, SnapshotVO snapshot) { @@ -522,10 +521,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { while ((pool = storageMgr.findStoragePool(dskCh, dc, pod.first(), null, null, null, poolsToAvoid)) != null) { break; - + } } - + VolumeInfo vol = this.volFactory.getVolume(volume.getId()); DataStore store = this.dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId()); @@ -551,22 +550,14 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { VMTemplateVO template, DataCenterVO dc, DiskOfferingVO diskOffering) { if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { - SearchCriteria sc = HostTemplateStatesSearch - .create(); - sc.setParameters("id", template.getId()); - sc.setParameters( - "state", - com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - sc.setJoinParameters("host", "dcId", dc.getId()); - - List sss = _vmTemplateHostDao.search(sc, null); - if (sss.size() == 0) { + TemplateDataStoreVO ss = this._vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dc.getId(), + VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (ss == null) { throw new CloudRuntimeException("Template " + template.getName() + " has not been completely downloaded to zone " + dc.getId()); } - VMTemplateHostVO ss = sss.get(0); return new DiskProfile(volume.getId(), volume.getVolumeType(), volume.getName(), diskOffering.getId(), ss.getSize(), @@ -586,7 +577,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId) { VolumeInfo createdVolume = null; - SnapshotVO snapshot = _snapshotDao.findById(snapshotId); + SnapshotVO snapshot = _snapshotDao.findById(snapshotId); createdVolume = createVolumeFromSnapshot(volume, snapshot); @@ -624,7 +615,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (result.isFailed()) { s_logger.debug("copy volume failed: " + result.getResult()); throw new CloudRuntimeException("copy volume failed: " + result.getResult()); - } + } return result.getVolume(); } catch (InterruptedException e) { s_logger.debug("Failed to copy volume: " + volume.getId(), e); @@ -642,11 +633,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { DiskOfferingVO diskOffering, List avoids, long size, HypervisorType hyperType) { StoragePool pool = null; - + if (diskOffering != null && diskOffering.isCustomized()) { diskOffering.setDiskSize(size); } - + DiskProfile dskCh = null; if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != template.getFormat()) { @@ -657,7 +648,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } dskCh.setHyperType(hyperType); - + final HashSet avoidPools = new HashSet( avoids); @@ -702,11 +693,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } } - + public String getRandomVolumeName() { return UUID.randomUUID().toString(); } - + private VolumeVO persistVolume(Account caller, long ownerId, Long zoneId, String volumeName, String url, String format) { @@ -749,7 +740,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { txn.commit(); return volume; } - + @Override public boolean volumeOnSharedStoragePool(VolumeVO volume) { Long poolId = volume.getPoolId(); @@ -1034,12 +1025,12 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throws ResourceAllocationException { Long newSize = null; boolean shrinkOk = cmd.getShrinkOk(); - + VolumeVO volume = _volsDao.findById(cmd.getEntityId()); if (volume == null) { throw new InvalidParameterValueException("No such volume"); } - + DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume .getDiskOfferingId()); DiskOfferingVO newDiskOffering = null; @@ -1196,9 +1187,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { "VM must be stopped or disk detached in order to resize with the Xen HV"); } } - + ResizeVolumePayload payload = new ResizeVolumePayload(newSize, shrinkOk, instanceName, hosts); - + try { VolumeInfo vol = this.volFactory.getVolume(volume.getId()); vol.addPayload(payload); @@ -1231,7 +1222,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return null; } - + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume") @@ -1271,7 +1262,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (!this.volService.destroyVolume(volume.getId())) { return false; } - + VMInstanceVO vmInstance = this._vmInstanceDao.findById(instanceId); if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) { @@ -1297,7 +1288,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } AsyncCallFuture future = this.volService.expungeVolumeAsync(this.volFactory.getVolume(volume.getId())); future.get(); - + } catch (Exception e) { s_logger.warn("Failed to expunge volume:", e); return false; @@ -1413,7 +1404,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } return toDiskProfile(vol, offering); } - + private String getSupportedImageFormatForCluster(Long clusterId) { ClusterVO cluster = ApiDBUtils.findClusterById(clusterId); @@ -1429,7 +1420,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return null; } } - + private VolumeInfo copyVolume(StoragePoolVO rootDiskPool , VolumeInfo volume, VMInstanceVO vm, VMTemplateVO rootDiskTmplt, DataCenterVO dcVO, HostPodVO pod, DiskOfferingVO diskVO, ServiceOfferingVO svo, HypervisorType rootDiskHyperType) throws NoTransitionException { @@ -1495,28 +1486,28 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { private boolean needMoveVolume(VolumeVO rootVolumeOfVm, VolumeInfo volume) { DataStore storeForRootVol = this.dataStoreMgr.getPrimaryDataStore(rootVolumeOfVm.getPoolId()); DataStore storeForDataVol = this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); - + Scope storeForRootStoreScope = storeForRootVol.getScope(); if (storeForRootStoreScope == null) { throw new CloudRuntimeException("Can't get scope of data store: " + storeForRootVol.getId()); } - + Scope storeForDataStoreScope = storeForDataVol.getScope(); if (storeForDataStoreScope == null) { throw new CloudRuntimeException("Can't get scope of data store: " + storeForDataVol.getId()); } - + if (storeForDataStoreScope.getScopeType() == ScopeType.ZONE) { return false; } - + if (storeForRootStoreScope.getScopeType() != storeForDataStoreScope.getScopeType()) { throw new CloudRuntimeException("Can't move volume between scope: " + storeForDataStoreScope.getScopeType() + " and " + storeForRootStoreScope.getScopeType()); } - + return !storeForRootStoreScope.isSameScope(storeForDataStoreScope); } - + private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volume, Long deviceId) { String errorMsg = "Failed to attach volume: " + volume.getName() + " to VM: " + vm.getHostName(); @@ -1568,7 +1559,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new CloudRuntimeException(errorMsg); } } - + private int getMaxDataVolumesSupported(UserVmVO vm) { Long hostId = vm.getHostId(); if (hostId == null) { @@ -1590,7 +1581,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return maxDataVolumesSupported.intValue(); } - + @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true) public Volume attachVolumeToVM(AttachVolumeCmd command) { @@ -1675,9 +1666,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { List vmSnapshots = _vmSnapshotDao.findByVm(vmId); if(vmSnapshots.size() > 0){ throw new InvalidParameterValueException( - "Unable to attach volume, please specify a VM that does not have VM snapshots"); + "Unable to attach volume, please specify a VM that does not have VM snapshots"); } - + // permission check _accountMgr.checkAccess(caller, null, true, volume, vm); @@ -1711,7 +1702,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { + " to a " + rootDiskHyperType + " vm"); } - + deviceId = getDeviceId(vmId, deviceId); VolumeInfo volumeOnPrimaryStorage = volume; if (volume.getState().equals(Volume.State.Allocated) @@ -1839,7 +1830,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { List vmSnapshots = _vmSnapshotDao.findByVm(vmId); if(vmSnapshots.size() > 0){ throw new InvalidParameterValueException( - "Unable to detach volume, the specified volume is attached to a VM that has VM snapshots."); + "Unable to detach volume, the specified volume is attached to a VM that has VM snapshots."); } AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor @@ -1906,10 +1897,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } } - - - + + + @DB protected VolumeVO switchVolume(VolumeVO existingVolume, @@ -1950,13 +1941,13 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } - + @Override public void release(VirtualMachineProfile profile) { // add code here } - + @Override @DB public void cleanupVolumes(long vmId) throws ConcurrentOperationException { @@ -2001,7 +1992,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { public Volume migrateVolume(MigrateVolumeCmd cmd) { Long volumeId = cmd.getVolumeId(); Long storagePoolId = cmd.getStoragePoolId(); - + VolumeVO vol = _volsDao.findById(volumeId); if (vol == null) { throw new InvalidParameterValueException( @@ -2034,8 +2025,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return newVol; } - - + + @DB protected Volume migrateVolume(Volume volume, StoragePool destPool) { VolumeInfo vol = this.volFactory.getVolume(volume.getId()); @@ -2093,7 +2084,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } return true; } - + @Override public void prepareForMigration( VirtualMachineProfile vm, @@ -2124,7 +2115,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } } - + private static enum VolumeTaskType { RECREATE, @@ -2141,7 +2132,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { this.volume = volume; } } - + private List getTasks(List vols, Map destVols) throws StorageUnavailableException { boolean recreate = _recreateSystemVmEnabled; List tasks = new ArrayList(); @@ -2229,11 +2220,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { tasks.add(task); } } - + return tasks; } - - private Pair recreateVolume(VolumeVO vol, VirtualMachineProfile vm, + + private Pair recreateVolume(VolumeVO vol, VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException { VolumeVO newVol; boolean recreate = _recreateSystemVmEnabled; @@ -2295,15 +2286,15 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new StorageUnavailableException("Unable to create " + newVol + ":" + e.toString(), destPool.getId()); } - + return new Pair(newVol, destPool); } - + @Override public void prepare(VirtualMachineProfile vm, DeployDestination dest) throws StorageUnavailableException, InsufficientStorageCapacityException, ConcurrentOperationException { - + if (dest == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("DeployDestination cannot be null, cannot prepare Volumes for the vm: " @@ -2338,7 +2329,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { vm.addDisk(new VolumeTO(vol, pool)); } } - + private Long getDeviceId(long vmId, Long deviceId) { // allocate deviceId List vols = _volsDao.findByInstance(vmId); @@ -2365,16 +2356,16 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } deviceId = Long.parseLong(devIds.iterator().next()); } - + return deviceId; } - + private boolean stateTransitTo(Volume vol, Volume.Event event) throws NoTransitionException { return _volStateMachine.transitTo(vol, event, null, _volsDao); } - + private String validateUrl(String url) { try { URI uri = new URI(url); @@ -2416,7 +2407,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } } - + @Override public boolean canVmRestartOnAnotherServer(long vmId) { List vols = _volsDao.findCreatedByInstance(vmId); @@ -2427,7 +2418,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } return true; } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { @@ -2448,21 +2439,6 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - HostTemplateStatesSearch = _vmTemplateHostDao.createSearchBuilder(); - HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity() - .getTemplateId(), SearchCriteria.Op.EQ); - HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity() - .getDownloadState(), SearchCriteria.Op.EQ); - - SearchBuilder HostSearch = _hostDao.createSearchBuilder(); - HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), - SearchCriteria.Op.EQ); - - HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity() - .getId(), HostTemplateStatesSearch.entity().getHostId(), - JoinBuilder.JoinType.INNER); - HostSearch.done(); - HostTemplateStatesSearch.done(); return true; } @@ -2480,7 +2456,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { public String getName() { return "Volume Manager"; } - + @Override public void destroyVolume(VolumeVO volume) { try { diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 7aa4efb23c3..f19ca308217 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -31,14 +31,10 @@ import javax.naming.ConfigurationException; 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 org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.log4j.Logger; -import org.springframework.context.annotation.Primary; -import org.springframework.stereotype.Component; - import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -101,19 +97,12 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.ScopeType; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.resource.DummySecondaryStorageResource; -import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; import com.cloud.template.TemplateManager; import com.cloud.user.Account; @@ -194,21 +183,14 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar private HostDao _hostDao; @Inject private StoragePoolHostDao _storagePoolHostDao; - - @Inject - private VMTemplateHostDao _vmTemplateHostDao; - @Inject private AgentManager _agentMgr; @Inject - protected SwiftManager _swiftMgr; - @Inject protected NetworkManager _networkMgr; @Inject protected NetworkModel _networkModel; @Inject protected SnapshotDao _snapshotDao; - @Inject private ClusterManager _clusterMgr; @@ -242,7 +224,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar protected IPAddressDao _ipAddressDao = null; @Inject protected RulesManager _rulesMgr; - @Inject + @Inject TemplateManager templateMgr; @Inject @@ -367,6 +349,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } + /* @Override public boolean deleteHost(Long hostId) { List snapshots = _snapshotDao.listByHostId(hostId); @@ -387,6 +370,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar return true; } + */ @Override public boolean generateVMSetupCommand(Long ssAHostId) { @@ -746,13 +730,13 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar s_logger.debug("No hypervisor host added in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm"); return false; } - + List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId)); if (stores.size() < 1) { s_logger.debug("No image store added in zone " + dataCenterId + ", wait until it is ready to launch secondary storage vm"); return false; } - + DataStore store = templateMgr.getImageStore(dataCenterId, template.getId()); if (store == null) { if (s_logger.isDebugEnabled()) { @@ -1390,10 +1374,11 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar @Override public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { - if (host.getType() == Host.Type.SecondaryStorage) { - deleteHost(host.getId()); - return new DeleteHostAnswer(false); - } + // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore. + //if (host.getType() == Host.Type.SecondaryStorage) { + // deleteHost(host.getId()); + // return new DeleteHostAnswer(false); + //} return null; } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java index 444727b30fd..0756c72d59e 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java @@ -47,7 +47,7 @@ public interface SecondaryStorageVmManager extends Manager { public Pair assignSecStorageVm(long zoneId, Command cmd); boolean generateSetupCommand(Long hostId); - boolean deleteHost(Long hostId); + //boolean deleteHost(Long hostId); public HostVO findSecondaryStorageHost(long dcId); public List listSecondaryStorageHostsInAllZones(); public List listSecondaryStorageHostsInOneZone(long dataCenterId); From 246e58013da5d4ea29063e2e6c169f962b635cd3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 23 Apr 2013 15:09:37 -0700 Subject: [PATCH 053/303] Remove VMTemplateHostDao reference from TemplateManagerImpl. --- .../SimulatorSecondaryDiscoverer.java | 12 +- server/src/com/cloud/api/ApiDBUtils.java | 15 - .../secondary/SecondaryStorageDiscoverer.java | 79 ++-- .../SecondaryStorageManagerImpl.java | 34 +- .../com/cloud/template/TemplateManager.java | 12 +- .../cloud/template/TemplateManagerImpl.java | 431 ++---------------- 6 files changed, 86 insertions(+), 497 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java index 6bbd90f986f..5197d6fb324 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorSecondaryDiscoverer.java @@ -115,16 +115,8 @@ public class SimulatorSecondaryDiscoverer extends SecondaryStorageDiscoverer imp @Override public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { - long hostId = host.getId(); - List snapshots = _snapshotDao.listByHostId(hostId); - if (snapshots != null && !snapshots.isEmpty()) { - throw new CloudRuntimeException("Cannot delete this secondary storage because there are still snapshots on it "); - } - _vmTemplateHostDao.deleteByHost(hostId); - host.setGuid(null); - _hostDao.update(hostId, host); - _hostDao.remove(hostId); - return new DeleteHostAnswer(true); + // no need to handle, since secondary storage is no longer a host anymore. + return null; } @Override diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 00358d7f0bd..41082b76d67 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -868,21 +868,6 @@ public class ApiDBUtils { return template; } - public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId) { - return findTemplateHostRef(templateId, zoneId, false); - } - - public static VMTemplateHostVO findTemplateHostRef(long templateId, long zoneId, boolean readyOnly) { - VMTemplateVO vmTemplate = findTemplateById(templateId); - if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { - List res = _templateHostDao.listByTemplateId(templateId); - return res.size() == 0 ? null : res.get(0); - } else { - return _templateMgr.getTemplateHostRef(zoneId, templateId, readyOnly); - } - } - - public static VolumeHostVO findVolumeHostRef(long volumeId, long zoneId) { return _volumeHostDao.findVolumeByZone(volumeId, zoneId); } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java index 3ca74a351e8..5094b66ddda 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageDiscoverer.java @@ -44,7 +44,6 @@ import com.cloud.resource.ServerResource; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.storage.resource.LocalSecondaryStorageResource; @@ -61,19 +60,17 @@ import com.cloud.utils.script.Script; @Local(value=Discoverer.class) public class SecondaryStorageDiscoverer extends DiscovererBase implements Discoverer { private static final Logger s_logger = Logger.getLogger(SecondaryStorageDiscoverer.class); - + long _timeout = 2 * 60 * 1000; // 2 minutes String _mountParent; boolean _useServiceVM = false; - + Random _random = new Random(System.currentTimeMillis()); @Inject protected HostDao _hostDao = null; @Inject protected VMTemplateDao _tmpltDao = null; @Inject - protected VMTemplateHostDao _vmTemplateHostDao = null; - @Inject protected VMTemplateZoneDao _vmTemplateZoneDao = null; @Inject protected VMTemplateDao _vmTemplateDao = null; @@ -81,10 +78,10 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov protected ConfigurationDao _configDao = null; @Inject protected AgentManager _agentMgr = null; - + protected SecondaryStorageDiscoverer() { } - + @Override public Map> find(long dcId, Long podId, Long clusterId, URI uri, String username, String password, List hostTags) { if (!uri.getScheme().equalsIgnoreCase("nfs") && !uri.getScheme().equalsIgnoreCase("file") @@ -103,14 +100,14 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov return null; } } - + protected Map> createNfsSecondaryStorageResource(long dcId, Long podId, URI uri) { - + if (_useServiceVM) { return createDummySecondaryStorageResource(dcId, podId, uri); } String mountStr = NfsUtils.uri2Mount(uri); - + Script script = new Script(true, "mount", _timeout, s_logger); String mntPoint = null; File file = null; @@ -118,12 +115,12 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov mntPoint = _mountParent + File.separator + Integer.toHexString(_random.nextInt(Integer.MAX_VALUE)); file = new File(mntPoint); } while (file.exists()); - + if (!file.mkdirs()) { s_logger.warn("Unable to make directory: " + mntPoint); return null; } - + script.add(mountStr, mntPoint); String result = script.execute(); if (result != null && !result.contains("already mounted")) { @@ -131,15 +128,15 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov file.delete(); return null; } - + script = new Script(true, "umount", 0, s_logger); script.add(mntPoint); script.execute(); - + file.delete(); - + Map> srs = new HashMap>(); - + NfsSecondaryStorageResource storage; if(_configDao.isPremium()) { Class impl; @@ -174,12 +171,12 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov } else { storage = new NfsSecondaryStorageResource(); } - + Map details = new HashMap(); details.put("mount.path", mountStr); details.put("orig.url", uri.toString()); details.put("mount.parent", _mountParent); - + Map params = new HashMap(); params.putAll(details); params.put("zone", Long.toString(dcId)); @@ -189,7 +186,7 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov params.put("guid", uri.toString()); params.put("secondary.storage.vm", "false"); params.put("max.template.iso.size", _configDao.getValue("max.template.iso.size")); - + try { storage.configure("Storage", params); } catch (ConfigurationException e) { @@ -197,22 +194,22 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov return null; } srs.put(storage, details); - + return srs; } - + protected Map> createLocalSecondaryStorageResource(long dcId, Long podId, URI uri) { Map> srs = new HashMap>(); - + LocalSecondaryStorageResource storage = new LocalSecondaryStorageResource(); storage = ComponentContext.inject(storage); - + Map details = new HashMap(); - + File file = new File(uri); details.put("mount.path", file.getAbsolutePath()); details.put("orig.url", uri.toString()); - + Map params = new HashMap(); params.putAll(details); params.put("zone", Long.toString(dcId)); @@ -220,7 +217,7 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov params.put("pod", podId.toString()); } params.put("guid", uri.toString()); - + try { storage.configure("Storage", params); } catch (ConfigurationException e) { @@ -228,21 +225,21 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov return null; } srs.put(storage, details); - + return srs; } - + protected Map> createDummySecondaryStorageResource(long dcId, Long podId, URI uri) { Map> srs = new HashMap>(); - + DummySecondaryStorageResource storage = new DummySecondaryStorageResource(_useServiceVM); storage = ComponentContext.inject(storage); - + Map details = new HashMap(); - + details.put("mount.path", uri.toString()); details.put("orig.url", uri.toString()); - + Map params = new HashMap(); params.putAll(details); params.put("zone", Long.toString(dcId)); @@ -250,7 +247,7 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov params.put("pod", podId.toString()); } params.put("guid", uri.toString()); - + try { storage.configure("Storage", params); } catch (ConfigurationException e) { @@ -258,26 +255,26 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov return null; } srs.put(storage, details); - + return srs; } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); - + _mountParent = _params.get("mount.parent"); if (_mountParent == null) { _mountParent = "/mnt"; } - + String useServiceVM = _params.get("secondary.storage.vm"); if ("true".equalsIgnoreCase(useServiceVM)){ _useServiceVM = true; } return true; } - + @Override public boolean matchHypervisor(String hypervisor) { if( hypervisor.equals("SecondaryStorage")) { @@ -291,7 +288,7 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov public Hypervisor.HypervisorType getHypervisorType() { return Hypervisor.HypervisorType.None; } - + @Override public void postDiscovery(List hosts, long msId) { if (_useServiceVM) { @@ -302,9 +299,9 @@ public class SecondaryStorageDiscoverer extends DiscovererBase implements Discov for (HostVO h: hosts) { associateTemplatesToZone(h.getId(), h.getDataCenterId()); } - + } - + private void associateTemplatesToZone(long hostId, long dcId){ VMTemplateZoneVO tmpltZone; diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index f19ca308217..e6a41e74a2f 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -46,7 +46,6 @@ import com.cloud.agent.api.SecStorageSetupCommand.Certificates; import com.cloud.agent.api.SecStorageVMSetupCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; -import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; @@ -97,12 +96,10 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.resource.DummySecondaryStorageResource; import com.cloud.storage.template.TemplateConstants; import com.cloud.template.TemplateManager; import com.cloud.user.Account; @@ -349,28 +346,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } - /* - @Override - public boolean deleteHost(Long hostId) { - List snapshots = _snapshotDao.listByHostId(hostId); - if( snapshots != null && !snapshots.isEmpty()) { - throw new CloudRuntimeException("Can not delete this secondary storage since it contains atleast one or more snapshots "); - } - if (!_swiftMgr.isSwiftEnabled()) { - List list = _templateDao.listPrivateTemplatesByHost(hostId); - if (list != null && !list.isEmpty()) { - throw new CloudRuntimeException("Can not delete this secondary storage since it contains private templates "); - } - } - _vmTemplateHostDao.deleteByHost(hostId); - HostVO host = _hostDao.findById(hostId); - host.setGuid(null); - _hostDao.update(hostId, host); - _hostDao.remove(hostId); - return true; - } - */ @Override public boolean generateVMSetupCommand(Long ssAHostId) { @@ -1328,7 +1304,9 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar @Override public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, List hostTags) { - /* Called when add secondary storage on UI */ + // Used to be Called when add secondary storage on UI through DummySecondaryStorageResource to update that host entry for Secondary Storage. + // Now since we move secondary storage from host table, this code is not needed to be invoked anymore. + /* StartupCommand firstCmd = startup[0]; if (!(firstCmd instanceof StartupStorageCommand)) { return null; @@ -1368,17 +1346,13 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar host.setStorageUrl(ssCmd.getNfsShare()); } } - + */ return host; } @Override public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { // Since secondary storage is moved out of host table, this class should not handle delete secondary storage anymore. - //if (host.getType() == Host.Type.SecondaryStorage) { - // deleteHost(host.getId()); - // return new DeleteHostAnswer(false); - //} return null; } diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index 9ab51e5a667..f44c0a7535b 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -96,22 +96,16 @@ public interface TemplateManager extends TemplateApiService{ boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef); - VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool); - - - VMTemplateHostVO findVmTemplateHost(long templateId, - StoragePool pool); - Pair getAbsoluteIsoPath(long templateId, long dataCenterId); String getSecondaryStorageURL(long zoneId); - HostVO getSecondaryStorageHost(long zoneId, long tmpltId); + //HostVO getSecondaryStorageHost(long zoneId, long tmpltId); DataStore getImageStore(long zoneId, long tmpltId); - VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, - boolean readyOnly); + // VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, + // boolean readyOnly); HostVO getSecondaryStorageHost(long zoneId); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 81cf29c0b0d..a9a43baf002 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -22,7 +22,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -31,9 +30,6 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -85,7 +81,6 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.downloadTemplateFromSwiftToSecondaryStorageCommand; import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.to.SwiftTO; @@ -141,7 +136,6 @@ import com.cloud.storage.Upload.Type; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateS3VO; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -158,7 +152,6 @@ import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDetailsDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateS3Dao; import com.cloud.storage.dao.VMTemplateSwiftDao; @@ -202,7 +195,6 @@ import com.cloud.vm.dao.VMInstanceDao; public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService { private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); @Inject VMTemplateDao _tmpltDao; - @Inject VMTemplateHostDao _tmpltHostDao; @Inject TemplateDataStoreDao _tmplStoreDao; @Inject VMTemplatePoolDao _tmpltPoolDao; @Inject VMTemplateZoneDao _tmpltZoneDao; @@ -252,32 +244,26 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject LaunchPermissionDao _launchPermissionDao; @Inject ProjectManager _projectMgr; @Inject - VolumeDataFactory volFactory; + VolumeDataFactory _volFactory; @Inject - TemplateDataFactory tmplFactory; + TemplateDataFactory _tmplFactory; @Inject - SnapshotDataFactory snapshotFactory; + SnapshotDataFactory _snapshotFactory; @Inject - TemplateService tmpltSvr; + TemplateService _tmpltSvr; @Inject - DataStoreManager dataStoreMgr; + DataStoreManager _dataStoreMgr; @Inject protected ResourceManager _resourceMgr; - @Inject VolumeManager volumeMgr; - @Inject VMTemplateHostDao templateHostDao; + @Inject VolumeManager _volumeMgr; @Inject ImageStoreDao _imageStoreDao; @Inject EndPointSelector _epSelector; int _primaryStorageDownloadWait; - protected SearchBuilder HostTemplateStatesSearch; - int _storagePoolMaxWaitSeconds = 3600; boolean _disableExtraction = false; ExecutorService _preloadExecutor; - ScheduledExecutorService _swiftTemplateSyncExecutor; - - private ScheduledExecutorService _s3TemplateSyncExecutor = null; @Inject protected List _adapters; @@ -337,9 +323,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, public DataStore getImageStore(String storeUuid, Long zoneId) { DataStore imageStore = null; if (storeUuid != null) { - imageStore = this.dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image); + imageStore = this._dataStoreMgr.getDataStore(storeUuid, DataStoreRole.Image); } else { - List stores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); if (stores.size() > 1) { throw new CloudRuntimeException("multiple image stores, don't know which one to use"); } @@ -443,7 +429,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - List ssStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + List ssStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); TemplateDataStoreVO tmpltStoreRef = null; ImageStoreEntity tmpltStore = null; @@ -533,7 +519,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, private void reallyRun() { s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId()); - StoragePool pol = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId()); + StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId()); prepareTemplateForCreate(template, pol); s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId()); } @@ -544,54 +530,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - String downloadTemplateFromSwiftToSecondaryStorage(long dcId, long templateId){ - VMTemplateVO template = _tmpltDao.findById(templateId); - if ( template == null ) { - String errMsg = " Can not find template " + templateId; - s_logger.warn(errMsg); - return errMsg; - } - VMTemplateSwiftVO tmpltSwift = _swiftMgr.findByTmpltId(templateId); - if ( tmpltSwift == null ) { - String errMsg = " Template " + templateId + " doesn't exist in swift"; - s_logger.warn(errMsg); - return errMsg; - } - SwiftTO swift = _swiftMgr.getSwiftTO(tmpltSwift.getSwiftId()); - if ( swift == null ) { - String errMsg = " Swift " + tmpltSwift.getSwiftId() + " doesn't exit ?"; - s_logger.warn(errMsg); - return errMsg; - } - HostVO secHost = _ssvmMgr.findSecondaryStorageHost(dcId); - if ( secHost == null ) { - String errMsg = "Can not find secondary storage in data center " + dcId; - s_logger.warn(errMsg); - return errMsg; - } - - downloadTemplateFromSwiftToSecondaryStorageCommand cmd = new downloadTemplateFromSwiftToSecondaryStorageCommand(swift, secHost.getName(), dcId, template.getAccountId(), templateId, - tmpltSwift.getPath(), _primaryStorageDownloadWait); - try { - Answer answer = _agentMgr.sendToSSVM(dcId, cmd); - if (answer == null || !answer.getResult()) { - String errMsg = "Failed to download template from Swift to secondary storage due to " + (answer == null ? "answer is null" : answer.getDetails()); - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); - } - String installPath = "template/tmpl/" + template.getAccountId() + "/" + template.getId() + "/" + tmpltSwift.getPath(); - VMTemplateHostVO tmpltHost = new VMTemplateHostVO(secHost.getId(), templateId, new Date(), 100, Status.DOWNLOADED, null, null, null, installPath, template.getUrl()); - tmpltHost.setSize(tmpltSwift.getSize()); - tmpltHost.setPhysicalSize(tmpltSwift.getPhysicalSize()); - _tmpltHostDao.persist(tmpltHost); - } catch (Exception e) { - String errMsg = "Failed to download template from Swift to secondary storage due to " + e.toString(); - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); - } - return null; - } String uploadTemplateToSwiftFromSecondaryStorage(VMTemplateHostVO templateHostRef) { Long templateId = templateHostRef.getTemplateId(); @@ -653,11 +592,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, long poolId = pool.getId(); long templateId = template.getId(); - long dcId = pool.getDataCenterId(); VMTemplateStoragePoolVO templateStoragePoolRef = null; TemplateDataStoreVO templateStoreRef = null; - long templateStoragePoolRefId; - String origUrl = null; templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); if (templateStoragePoolRef != null) { @@ -673,8 +609,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - templateStoreRef = findVmTemplateImageStore(templateId, pool); - + templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED); if (templateStoreRef == null) { s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); return null; @@ -685,22 +620,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool"); } - /* - HostVO sh = _hostDao.findById(templateStoreRef.getHostId()); - origUrl = sh.getStorageUrl(); - if (origUrl == null) { - throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString()); - } - */ if (templateStoragePoolRef == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Downloading template " + templateId + " to pool " + poolId); } - DataStore srcSecStore = this.dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image); - TemplateInfo srcTemplate = this.tmplFactory.getTemplate(templateId, srcSecStore); + DataStore srcSecStore = this._dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image); + TemplateInfo srcTemplate = this._tmplFactory.getTemplate(templateId, srcSecStore); - AsyncCallFuture future = this.tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool); + AsyncCallFuture future = this._tmpltSvr.prepareTemplateOnPrimary(srcTemplate, pool); try { TemplateApiResult result = future.get(); if (result.isFailed()) { @@ -718,61 +646,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return null; } - private TemplateDataStoreVO findVmTemplateImageStore(long templateId, - StoragePool pool) { - long dcId = pool.getDataCenterId(); - - List secStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId)); - - if ( secStores == null ){ - s_logger.error("No image store found to download template " + templateId + " primary storage!"); - return null; - } - for (DataStore store : secStores ){ - List templStores = this._tmplStoreDao.listByTemplateStoreDownloadStatus(templateId, store.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if (templStores != null && !templStores.isEmpty()) { - Collections.shuffle(templStores); - return templStores.get(0); - } - } - - return null; - } - - - @Override - public VMTemplateHostVO findVmTemplateHost(long templateId, - StoragePool pool) { - long dcId = pool.getDataCenterId(); - Long podId = pool.getPodId(); - - List secHosts = _ssvmMgr - .listSecondaryStorageHostsInOneZone(dcId); - - - if (secHosts.size() == 1) { - VMTemplateHostVO templateHostVO = this._tmpltHostDao - .findByHostTemplate(secHosts.get(0).getId(), templateId); - return templateHostVO; - } - if (podId != null) { - List templHosts = this._tmpltHostDao - .listByTemplateStatus(templateId, dcId, podId, - VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if (templHosts != null && !templHosts.isEmpty()) { - Collections.shuffle(templHosts); - return templHosts.get(0); - } - } - List templHosts = this._tmpltHostDao - .listByTemplateStatus(templateId, dcId, - VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if (templHosts != null && !templHosts.isEmpty()) { - Collections.shuffle(templHosts); - return templHosts.get(0); - } - return null; - } @Override public String getChecksum(Long hostId, String templatePath) { @@ -807,41 +680,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } - @Override - @DB - public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) { - template = _tmpltDao.findById(template.getId(), true); - - long poolId = pool.getId(); - long templateId = template.getId(); - long dcId = pool.getDataCenterId(); - VMTemplateStoragePoolVO templateStoragePoolRef = null; - VMTemplateHostVO templateHostRef = null; - long templateStoragePoolRefId; - String origUrl = null; - - templateHostRef = findVmTemplateHost(templateId, pool); - - if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) { - String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId); - if (result != null) { - s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); - return null; - } - result = _s3Mgr.downloadTemplateFromS3ToSecondaryStorage(dcId, - templateId, _primaryStorageDownloadWait); - if (result != null) { - s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); - return null; - } - templateHostRef = findVmTemplateHost(templateId, pool); - if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) { - s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); - return null; - } - } - return templateHostRef; - } @Override @DB @@ -870,7 +708,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, long tmpltId = template.getId(); long dstZoneId = dstZone.getId(); // find all eligible image stores for the destination zone - List dstSecStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId)); + List dstSecStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId)); if (dstSecStores == null || dstSecStores.isEmpty() ) { throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId()); } @@ -895,7 +733,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Transaction txn = Transaction.currentTxn(); txn.start(); - TemplateInfo srcTemplate = this.tmplFactory.getTemplate(template.getId(), srcSecStore); + TemplateInfo srcTemplate = this._tmplFactory.getTemplate(template.getId(), srcSecStore); // Copy will just find one eligible image store for the destination zone // and copy template there, not propagate to all image stores // for that zone @@ -930,7 +768,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, txn.commit(); } - AsyncCallFuture future = this.tmpltSvr.copyTemplate(srcTemplate, dstSecStore); + AsyncCallFuture future = this._tmpltSvr.copyTemplate(srcTemplate, dstSecStore); try { TemplateApiResult result = future.get(); if (result.isFailed()) { @@ -1051,7 +889,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) { - StoragePool pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); + StoragePool pool = (StoragePool)this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); @@ -1077,100 +915,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } - void swiftTemplateSync() { - GlobalLock swiftTemplateSyncLock = GlobalLock.getInternLock("templatemgr.swiftTemplateSync"); - try { - if (!_swiftMgr.isSwiftEnabled()) { - return; - } - List hypers = _clusterDao.getAvailableHypervisorInZone(null); - List templates = _tmpltDao.listByHypervisorType(hypers); - List templateIds = new ArrayList(); - for (VMTemplateVO template : templates) { - if (template.getTemplateType() != TemplateType.PERHOST) { - templateIds.add(template.getId()); - } - } - List templtSwiftRefs = _tmpltSwiftDao.listAll(); - for (VMTemplateSwiftVO templtSwiftRef : templtSwiftRefs) { - templateIds.remove((Long) templtSwiftRef.getTemplateId()); - } - if (templateIds.size() < 1) { - return; - } - if (swiftTemplateSyncLock.lock(3)) { - try { - List templtHostRefs = _tmpltHostDao.listByState(VMTemplateHostVO.Status.DOWNLOADED); - for (VMTemplateHostVO templtHostRef : templtHostRefs) { - if (templtHostRef.getDestroyed()) { - continue; - } - if (!templateIds.contains(templtHostRef.getTemplateId())) { - continue; - } - try { - uploadTemplateToSwiftFromSecondaryStorage(templtHostRef); - } catch (Exception e) { - s_logger.debug("failed to upload template " + templtHostRef.getTemplateId() + " to Swift due to " + e.toString()); - } - } - } catch (Throwable e) { - s_logger.error("Problem with sync swift template due to " + e.toString(), e); - } finally { - swiftTemplateSyncLock.unlock(); - } - } - } catch (Throwable e) { - s_logger.error("Problem with sync swift template due to " + e.toString(), e); - } finally { - swiftTemplateSyncLock.releaseRef(); - } - } - - private Runnable getSwiftTemplateSyncTask() { - return new Runnable() { - @Override - public void run() { - if (s_logger.isDebugEnabled()) { - s_logger.trace("Start Swift Template sync at" + (new Date())); - } - swiftTemplateSync(); - if (s_logger.isTraceEnabled()) { - s_logger.trace("Finish Swift Template sync at" + (new Date())); - } - } - }; - } @Override public boolean start() { - _swiftTemplateSyncExecutor.scheduleAtFixedRate(getSwiftTemplateSyncTask(), 60, 60, TimeUnit.SECONDS); - - if (_s3TemplateSyncExecutor != null) { - - final int initialDelay = 60; - final int period = 60; - - _s3TemplateSyncExecutor.scheduleAtFixedRate(new S3SyncTask( - this._tmpltDao, this._s3Mgr), initialDelay, period, - TimeUnit.SECONDS); - s_logger.info(String.format("Started S3 sync task to execute " - + "execute every %1$s after an initial delay of %2$s.", - period, initialDelay)); - - } - return true; } @Override public boolean stop() { - _swiftTemplateSyncExecutor.shutdownNow(); - - if (_s3TemplateSyncExecutor != null) { - _s3TemplateSyncExecutor.shutdownNow(); - } - return true; } @@ -1186,28 +938,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString()); _disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction); - HostTemplateStatesSearch = _tmpltHostDao.createSearchBuilder(); - HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); - - SearchBuilder HostSearch = _hostDao.createSearchBuilder(); - HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - - HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER); - HostSearch.done(); - HostTemplateStatesSearch.done(); _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); _preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader")); - _swiftTemplateSyncExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("swift-template-sync-Executor")); - if (_s3Mgr.isS3Enabled()) { - _s3TemplateSyncExecutor = Executors - .newSingleThreadScheduledExecutor(new NamedThreadFactory( - "s3-template-sync")); - } else { - s_logger.info("S3 secondary storage synchronization is disabled."); - } return true; } @@ -1715,21 +1449,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, VolumeVO volume = null; try { - TemplateInfo tmplInfo = this.tmplFactory.getTemplate(templateId); + TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId); snapshot = _snapshotDao.findById(snapshotId); ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); - List store = this.dataStoreMgr.getImageStoresByScope(scope); + List store = this._dataStoreMgr.getImageStoresByScope(scope); if (store.size() > 1) { throw new CloudRuntimeException("muliple image data store, don't know which one to use"); } AsyncCallFuture future = null; if (snapshotId != null) { - SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshotId); - future = this.tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); + SnapshotInfo snapInfo = this._snapshotFactory.getSnapshot(snapshotId); + future = this._tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); } else if (volumeId != null) { volume = _volumeDao.findById(volumeId); - VolumeInfo volInfo = this.volFactory.getVolume(volumeId); - future = this.tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0)); + VolumeInfo volInfo = this._volFactory.getVolume(volumeId); + future = this._tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0)); } else { throw new CloudRuntimeException( "Creating private Template need to specify snapshotId or volumeId"); @@ -1873,7 +1607,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // If private template is created from Volume, check that the volume // will not be active when the private template is // created - if (!this.volumeMgr.volumeInactive(volume)) { + if (!this._volumeMgr.volumeInactive(volume)) { String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first"; @@ -1995,29 +1729,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public Pair getAbsoluteIsoPath(long templateId, long dataCenterId) { - String isoPath = null; - - List storageHosts = _resourceMgr.listAllHostsInOneZoneByType( - Host.Type.SecondaryStorage, dataCenterId); - if (storageHosts != null) { - for (HostVO storageHost : storageHosts) { - List templateHostVOs = this._tmpltHostDao - .listByTemplateHostStatus( - templateId, - storageHost.getId(), - VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if (templateHostVOs != null && !templateHostVOs.isEmpty()) { - VMTemplateHostVO tmpHostVO = templateHostVOs.get(0); - isoPath = storageHost.getStorageUrl() + "/" - + tmpHostVO.getInstallPath(); - return new Pair(isoPath, - storageHost.getStorageUrl()); - } - } + TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId, + VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (templateStoreRef == null) { + throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + dataCenterId); } - s_logger.warn("Unable to find secondary storage in zone id=" - + dataCenterId); - return null; + DataStore store = this._dataStoreMgr.getDataStore(templateStoreRef.getDataStoreId(), DataStoreRole.Image); + String isoPath = store.getUri() + "/" + templateStoreRef.getInstallPath(); + return new Pair(isoPath, store.getUri()); } @Override @@ -2035,7 +1754,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // get the image store where a template in a given zone is downloaded to, just pick one is enough. @Override public DataStore getImageStore(long zoneId, long tmpltId) { - List stores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); if (stores == null || stores.size() == 0) { return null; } @@ -2049,54 +1768,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return null; } - @Override - public HostVO getSecondaryStorageHost(long zoneId, long tmpltId) { - List hosts = _ssvmMgr - .listSecondaryStorageHostsInOneZone(zoneId); - if (hosts == null || hosts.size() == 0) { - return null; - } - for (HostVO host : hosts) { - VMTemplateHostVO tmpltHost = this._tmpltHostDao.findByHostTemplate( - host.getId(), tmpltId); - if (tmpltHost != null - && !tmpltHost.getDestroyed() - && tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - return host; - } - } - return null; - } - @Override - public VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, - boolean readyOnly) { - // readyOnly flag is not used at all - List hosts = _ssvmMgr - .listSecondaryStorageHostsInOneZone(zoneId); - if (hosts == null || hosts.size() == 0) { - return null; - } - VMTemplateHostVO inProgress = null; - VMTemplateHostVO other = null; - for (HostVO host : hosts) { - VMTemplateHostVO tmpltHost = this._tmpltHostDao.findByHostTemplate( - host.getId(), tmpltId); - if (tmpltHost != null && !tmpltHost.getDestroyed()) { - if (tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - return tmpltHost; - } else if (tmpltHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - inProgress = tmpltHost; - } else { - other = tmpltHost; - } - } - } - if (inProgress != null) { - return inProgress; - } - return other; - } @Override public HostVO getSecondaryStorageHost(long zoneId) { @@ -2130,45 +1802,20 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public Long getTemplateSize(long templateId, long zoneId) { - SearchCriteria sc = HostTemplateStatesSearch.create(); - sc.setParameters("id", templateId); - sc.setParameters( - "state", - com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - sc.setJoinParameters("host", "dcId", zoneId); - List tsvs = _tmpltSwiftDao - .listByTemplateId(templateId); - Long size = null; - if (tsvs != null && tsvs.size() > 0) { - size = tsvs.get(0).getSize(); + TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, + VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (templateStoreRef == null) { + throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + zoneId); } + return templateStoreRef.getSize(); - if (size == null && _s3Mgr.isS3Enabled()) { - VMTemplateS3VO vmTemplateS3VO = _vmS3TemplateDao - .findOneByTemplateId(templateId); - if (vmTemplateS3VO != null) { - size = vmTemplateS3VO.getSize(); - } - } - - if (size == null) { - List sss = this.templateHostDao.search(sc, null); - if (sss == null || sss.size() == 0) { - throw new CloudRuntimeException("Template " - + templateId - + " has not been completely downloaded to zone " - + zoneId); - } - size = sss.get(0).getSize(); - } - return size; } // find image store where this template is located @Override public List getImageStoreByTemplate(long templateId, Long zoneId) { // find all eligible image stores for this zone scope - List imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + List imageStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); if ( imageStores == null || imageStores.size() == 0 ){ return null; } From 7ec0882dcafc6308a50b650c549cab56b586d316 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 23 Apr 2013 16:07:44 -0700 Subject: [PATCH 054/303] Remove VMTemplateHostDao reference from BareMetalTemplateAdapter, also make store_id in template_store_ref table nullable to accommodate baremetal case. --- .../datastore/db/TemplateDataStoreVO.java | 6 +- .../manager/BareMetalTemplateAdapter.java | 122 ++++++++---------- .../cloud/template/TemplateAdapterBase.java | 25 ++-- setup/db/db/schema-410to420.sql | 7 +- 4 files changed, 78 insertions(+), 82 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index f1ca62b626a..62b5c8771e7 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -49,7 +49,7 @@ public class TemplateDataStoreVO implements StateObject dcs = _dcDao.listAllIncludingRemoved(); for (DataCenterVO dc : dcs) { @@ -90,53 +91,39 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem return profile; } - + @Override public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { throw new CloudRuntimeException("Baremetal doesn't support ISO template"); } - - private void templateCreateUsage(VMTemplateVO template, HostVO host) { + + private void templateCreateUsage(VMTemplateVO template, long dcId) { if (template.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), host.getDataCenterId(), + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, template.getAccountId(), dcId, template.getId(), template.getName(), null, template.getSourceTemplateId(), 0L); _usageEventDao.persist(usageEvent); } } - + @Override public VMTemplateVO create(TemplateProfile profile) { VMTemplateVO template = persistTemplate(profile); Long zoneId = profile.getZoneId(); - - /* There is no secondary storage vm for baremetal, we use pxe server id. - * Tempalte is not bound to pxeserver right now, and we assume the pxeserver - * cannot be removed once it was added. so we use host id of first found pxe - * server as reference in template_host_ref. - * This maybe a FIXME in future. - */ - VMTemplateHostVO vmTemplateHost = null; + + // create an entry at template_store_ref with store_id = null to represent that this template is ready for use. + TemplateDataStoreVO vmTemplateHost = new TemplateDataStoreVO(null, template.getId(), new Date(), 100, + Status.DOWNLOADED, null, null, null, null, template.getUrl()); + this._tmpltStoreDao.persist(vmTemplateHost); + if (zoneId == null || zoneId == -1) { List dcs = _dcDao.listAllIncludingRemoved(); - for (DataCenterVO dc : dcs) { - HostVO pxe = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, dc.getId()).get(0); - - vmTemplateHost = _tmpltHostDao.findByHostTemplate(dc.getId(), template.getId()); - if (vmTemplateHost == null) { - vmTemplateHost = new VMTemplateHostVO(pxe.getId(), template.getId(), new Date(), 100, - Status.DOWNLOADED, null, null, null, null, template.getUrl()); - _tmpltHostDao.persist(vmTemplateHost); - templateCreateUsage(template, pxe); - } + if ( dcs != null && dcs.size() > 0 ){ + templateCreateUsage(template, dcs.get(0).getId()); } } else { - HostVO pxe = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.BaremetalPxe, zoneId).get(0); - vmTemplateHost = new VMTemplateHostVO(pxe.getId(), template.getId(), new Date(), 100, - Status.DOWNLOADED, null, null, null, null, template.getUrl()); - _tmpltHostDao.persist(vmTemplateHost); - templateCreateUsage(template, pxe); + templateCreateUsage(template, zoneId); } - + _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.secondary_storage, UriUtils.getRemoteSize(profile.getUrl())); @@ -146,65 +133,70 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { throw new CloudRuntimeException("Baremetal doesn't support ISO, how the delete get here???"); } - + @Override @DB public boolean delete(TemplateProfile profile) { VMTemplateVO template = profile.getTemplate(); Long templateId = template.getId(); boolean success = true; String zoneName; - boolean isAllZone; - + if (!template.isCrossZones() && profile.getZoneId() != null) { - isAllZone = false; zoneName = profile.getZoneId().toString(); } else { zoneName = "all zones"; - isAllZone = true; } - + s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName); Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); String eventType = EventTypes.EVENT_TEMPLATE_DELETE; - List templateHostVOs = _tmpltHostDao.listByTemplateId(templateId); - - for (VMTemplateHostVO vo : templateHostVOs) { - VMTemplateHostVO lock = null; - try { - HostVO pxeServer = _hostDao.findById(vo.getHostId()); - if (!isAllZone && pxeServer.getDataCenterId() != profile.getZoneId()) { - continue; - } + List templateHostVOs = this._tmpltStoreDao.listByTemplate(templateId); - lock = _tmpltHostDao.acquireInLockTable(vo.getId()); + for (TemplateDataStoreVO vo : templateHostVOs) { + TemplateDataStoreVO lock = null; + try { + lock = _tmpltStoreDao.acquireInLockTable(vo.getId()); if (lock == null) { - s_logger.debug("Failed to acquire lock when deleting templateHostVO with ID: " + vo.getId()); + s_logger.debug("Failed to acquire lock when deleting templateDataStoreVO with ID: " + vo.getId()); success = false; break; } vo.setDestroyed(true); - _tmpltHostDao.update(vo.getId(), vo); - VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(pxeServer.getDataCenterId(), templateId); - if (templateZone != null) { - _tmpltZoneDao.remove(templateZone.getId()); - } + _tmpltStoreDao.update(vo.getId(), vo); + - UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), pxeServer.getDataCenterId(), templateId, null); - _usageEventDao.persist(usageEvent); } finally { if (lock != null) { - _tmpltHostDao.releaseFromLockTable(lock.getId()); + _tmpltStoreDao.releaseFromLockTable(lock.getId()); } } } - + + if ( profile.getZoneId() != null ){ + UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), profile.getZoneId(), templateId, null); + _usageEventDao.persist(usageEvent); + } + else{ + List dcs = _dcDao.listAllIncludingRemoved(); + for ( DataCenterVO dc : dcs){ + UsageEventVO usageEvent = new UsageEventVO(eventType, account.getId(), dc.getId(), templateId, null); + _usageEventDao.persist(usageEvent); + } + } + + VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(profile.getZoneId(), templateId); + + if (templateZone != null) { + _tmpltZoneDao.remove(templateZone.getId()); + } + s_logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName); - + // If there are no more non-destroyed template host entries for this template, delete it - if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) { + if (success && (_tmpltStoreDao.listByTemplate(templateId).size() == 0)) { long accountId = template.getAccountId(); - + VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId); try { @@ -225,7 +217,7 @@ public class BareMetalTemplateAdapter extends TemplateAdapterBase implements Tem } s_logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed."); } - + return success; } } diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index 9826298d50b..f65b3641493 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -26,7 +26,6 @@ import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.log4j.Logger; @@ -47,12 +46,10 @@ import com.cloud.org.Grouping; import com.cloud.storage.GuestOS; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.DataStoreRole; import com.cloud.storage.TemplateProfile; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -76,7 +73,6 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat protected @Inject AccountManager _accountMgr; protected @Inject DataCenterDao _dcDao; protected @Inject VMTemplateDao _tmpltDao; - protected @Inject VMTemplateHostDao _tmpltHostDao; protected @Inject TemplateDataStoreDao _tmpltStoreDao; protected @Inject VMTemplateZoneDao _tmpltZoneDao; protected @Inject UsageEventDao _usageEventDao; @@ -99,7 +95,8 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); } - public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, + @Override + public TemplateProfile prepare(boolean isIso, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, String accountName, Long domainId, String chksum, Boolean bootable, Map details) throws ResourceAllocationException { @@ -107,7 +104,8 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat chksum, bootable, null, null, details, false); } - public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, + @Override + public TemplateProfile prepare(boolean isIso, long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHVM, String url, Boolean isPublic, Boolean featured, Boolean isExtractable, String format, Long guestOSId, Long zoneId, HypervisorType hypervisorType, String chksum, Boolean bootable, String templateTag, Account templateOwner, Map details, Boolean sshkeyEnabled) throws ResourceAllocationException { @@ -228,7 +226,8 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat cmd.getChecksum(), true, cmd.getTemplateTag(), owner, cmd.getDetails(), cmd.isSshKeyEnabled()); } - public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { + @Override + public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { //check if the caller can operate with the template owner Account caller = UserContext.current().getCaller(); Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); @@ -304,7 +303,8 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat return userId; } - public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { + @Override + public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { Long templateId = cmd.getId(); Long userId = UserContext.current().getCallerUserId(); Account account = UserContext.current().getCaller(); @@ -329,7 +329,8 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat return new TemplateProfile(userId, template, zoneId); } - public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { + @Override + public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { Long templateId = cmd.getId(); Long userId = UserContext.current().getCallerUserId(); Account account = UserContext.current().getCaller(); @@ -354,6 +355,8 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat return new TemplateProfile(userId, template, zoneId); } - abstract public VMTemplateVO create(TemplateProfile profile); - abstract public boolean delete(TemplateProfile profile); + @Override + abstract public VMTemplateVO create(TemplateProfile profile); + @Override + abstract public boolean delete(TemplateProfile profile); } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 6a7365f9054..9519266e7f5 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -115,10 +115,11 @@ CREATE VIEW `cloud`.`image_store_view` AS left join `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id; - +-- here we have to allow null for store_id to accomodate baremetal case to search for ready templates since template state is only stored in this table +-- FK also commented out due to this CREATE TABLE `cloud`.`template_store_ref` ( `id` bigint unsigned NOT NULL auto_increment, - `store_id` bigint unsigned NOT NULL, + `store_id` bigint unsigned, `template_id` bigint unsigned NOT NULL, `created` DATETIME NOT NULL, `last_updated` DATETIME, @@ -135,7 +136,7 @@ CREATE TABLE `cloud`.`template_store_ref` ( `destroyed` tinyint(1) COMMENT 'indicates whether the template_store entry was destroyed by the user or not', `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', PRIMARY KEY (`id`), - CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, +-- CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, INDEX `i_template_store_ref__store_id`(`store_id`), CONSTRAINT `fk_template_store_ref__template_id` FOREIGN KEY `fk_template_store_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), INDEX `i_template_store_ref__template_id`(`template_id`) From 7543f314a7c3e0b2492ca5d47c6e075bd5bc4ae2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 23 Apr 2013 17:12:21 -0700 Subject: [PATCH 055/303] Remove more VMTemplateHostDao references. --- .../cloud/resource/SimulatorDiscoverer.java | 3 - .../xen/discoverer/XcpServerDiscoverer.java | 144 +++++++++--------- .../CloudStackImageStoreDriverImpl.java | 10 +- .../driver/S3ImageStoreDriverImpl.java | 3 - .../driver/SwiftImageStoreDriverImpl.java | 3 - .../impl/UserConcentratedAllocator.java | 58 ++++--- server/src/com/cloud/api/ApiDBUtils.java | 15 -- .../consoleproxy/ConsoleProxyManagerImpl.java | 36 ++--- .../ResourceLimitManagerImpl.java | 12 +- .../storage/upload/UploadMonitorImpl.java | 5 - .../src/com/cloud/vm/UserVmManagerImpl.java | 19 +-- 11 files changed, 135 insertions(+), 173 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java index a9f61341c9d..4f2be7d2d0d 100755 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/SimulatorDiscoverer.java @@ -52,9 +52,7 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; -import org.springframework.stereotype.Component; @Local(value = Discoverer.class) public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, Listener, ResourceStateAdapter { @@ -63,7 +61,6 @@ public class SimulatorDiscoverer extends DiscovererBase implements Discoverer, L @Inject HostDao _hostDao; @Inject VMTemplateDao _vmTemplateDao; - @Inject VMTemplateHostDao _vmTemplateHostDao; @Inject VMTemplateZoneDao _vmTemplateZoneDao; @Inject ClusterDao _clusterDao; @Inject AgentManager _agentMgr = null; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 195ab309872..83ee1500e40 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -11,7 +11,7 @@ // 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 +// KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package com.cloud.hypervisor.xen.discoverer; @@ -83,7 +83,6 @@ import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.user.Account; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.SearchCriteria.Op; @@ -115,14 +114,13 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L @Inject protected AlertManager _alertMgr; @Inject protected AgentManager _agentMgr; @Inject VMTemplateDao _tmpltDao; - @Inject VMTemplateHostDao _vmTemplateHostDao; @Inject ResourceManager _resourceMgr; @Inject HostPodDao _podDao; @Inject DataCenterDao _dcDao; - + protected XcpServerDiscoverer() { } - + void setClusterGuid(ClusterVO cluster, String guid) { cluster.setGuid(guid); try { @@ -156,43 +154,43 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L String msg = "must specify cluster Id when add host"; s_logger.debug(msg); throw new RuntimeException(msg); - } - + } + if (podId == null) { String msg = "must specify pod Id when add host"; s_logger.debug(msg); throw new RuntimeException(msg); } - + ClusterVO cluster = _clusterDao.findById(clusterId); if(cluster == null || cluster.getHypervisorType() != HypervisorType.XenServer) { if(s_logger.isInfoEnabled()) s_logger.info("invalid cluster id or cluster is not for XenServer hypervisors"); return null; } - + try { List eHosts = _resourceMgr.listAllHostsInCluster(clusterId); if( eHosts.size() > 0 ) { HostVO eHost = eHosts.get(0); _hostDao.loadDetails(eHost); - } + } String hostname = url.getHost(); InetAddress ia = InetAddress.getByName(hostname); - String hostIp = ia.getHostAddress(); + String hostIp = ia.getHostAddress(); Queue pass=new LinkedList(); pass.add(password); - String masterIp = _connPool.getMasterIp(hostIp, username, pass); + String masterIp = _connPool.getMasterIp(hostIp, username, pass); conn = _connPool.masterConnect(masterIp, username, pass); if (conn == null) { String msg = "Unable to get a connection to " + url; s_logger.debug(msg); throw new DiscoveryException(msg); } - + Set pools = Pool.getAll(conn); Pool pool = pools.iterator().next(); - Pool.Record pr = pool.getRecord(conn); + Pool.Record pr = pool.getRecord(conn); String poolUuid = pr.uuid; Map hosts = Host.getAllRecords(conn); @@ -229,22 +227,22 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L conn.dispose(); conn = null; } - + poolUuid = clu.getGuid(); _clusterDao.update(clusterId, clu); - - + + if (_checkHvm) { for (Map.Entry entry : hosts.entrySet()) { Host.Record record = entry.getValue(); - + boolean support_hvm = false; for ( String capability : record.capabilities ) { if(capability.contains("hvm")) { support_hvm = true; break; } - } + } if( !support_hvm ) { String msg = "Unable to add host " + record.address + " because it doesn't support hvm"; _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); @@ -257,7 +255,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L for (Map.Entry entry : hosts.entrySet()) { Host.Record record = entry.getValue(); String hostAddr = record.address; - + String prodVersion = record.softwareVersion.get("product_version"); if (prodVersion == null) { prodVersion = record.softwareVersion.get("platform_version"); @@ -267,18 +265,18 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (hostOS == null) { hostOS = record.softwareVersion.get("platform_name"); } - + String hostOSVer = prodVersion; String hostKernelVer = record.softwareVersion.get("linux"); if (_resourceMgr.findHostByGuid(record.uuid) != null) { s_logger.debug("Skipping " + record.address + " because " + record.uuid + " is already in the database."); continue; - } + } CitrixResourceBase resource = createServerResource(dcId, podId, record); s_logger.info("Found host " + record.hostname + " ip=" + record.address + " product version=" + prodVersion); - + Map details = new HashMap(); Map params = new HashMap(); details.put("url", hostAddr); @@ -292,26 +290,26 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L params.put("cluster", clusterId.toString()); params.put("pool", poolUuid); params.put("ipaddress", record.address); - + details.put(HostInfo.HOST_OS, hostOS); details.put(HostInfo.HOST_OS_VERSION, hostOSVer); details.put(HostInfo.HOST_OS_KERNEL_VERSION, hostKernelVer); details.put(HostInfo.HYPERVISOR_VERSION, xenVersion); - + String privateNetworkLabel = _networkMgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.XenServer); String storageNetworkLabel = _networkMgr.getDefaultStorageTrafficLabel(dcId, HypervisorType.XenServer); - + if (!params.containsKey("private.network.device") && privateNetworkLabel != null) { params.put("private.network.device", privateNetworkLabel); details.put("private.network.device", privateNetworkLabel); } - + if (!params.containsKey("storage.network.device1") && storageNetworkLabel != null) { params.put("storage.network.device1", storageNetworkLabel); details.put("storage.network.device1", storageNetworkLabel); } - + params.put("wait", Integer.toString(_wait)); details.put("wait", Integer.toString(_wait)); params.put("migratewait", _configDao.getValue(Config.MigrateWait.toString())); @@ -327,8 +325,8 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } resource.start(); resources.put(resource, details); - } - } catch (SessionAuthenticationFailed e) { + } + } catch (SessionAuthenticationFailed e) { throw new DiscoveredWithErrorException("Authentication error"); } catch (XenAPIException e) { s_logger.warn("XenAPI exception", e); @@ -345,27 +343,27 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } return resources; } - + String getPoolUuid(Connection conn) throws XenAPIException, XmlRpcException { Map pools = Pool.getAllRecords(conn); assert pools.size() == 1 : "Pools size is " + pools.size(); return pools.values().iterator().next().uuid; } - + protected void addSamePool(Connection conn, Map> resources) throws XenAPIException, XmlRpcException { Map hps = Pool.getAllRecords(conn); assert (hps.size() == 1) : "How can it be more than one but it's actually " + hps.size(); - + // This is the pool. String poolUuid = hps.values().iterator().next().uuid; - + for (Map details : resources.values()) { details.put("pool", poolUuid); } } - + protected boolean addHostsToPool(Connection conn, String hostIp, Long clusterId) throws XenAPIException, XmlRpcException, DiscoveryException { - + List hosts; hosts = _resourceMgr.listAllHostsInCluster(clusterId); @@ -400,19 +398,19 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L hostConn = null; } } - + if (masterIp == null) { s_logger.warn("Unable to reach the pool master of the existing cluster"); throw new CloudRuntimeException("Unable to reach the pool master of the existing cluster"); } - + if( !_connPool.joinPool(conn, hostIp, masterIp, username, pass) ){ s_logger.warn("Unable to join the pool"); throw new DiscoveryException("Unable to join the pool"); - } + } return true; } - + protected CitrixResourceBase createServerResource(long dcId, Long podId, Host.Record record) { String prodBrand = record.softwareVersion.get("product_brand"); if (prodBrand == null) { @@ -430,7 +428,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if(prodBrand.equals("XCP") && (prodVersion.equals("1.0.0") || prodVersion.equals("1.1.0") || prodVersion.equals("5.6.100") || prodVersion.startsWith("1.4") || prodVersion.startsWith("1.6"))) return new XcpServerResource(); - if(prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) + if(prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) return new XenServer56Resource(); if (prodBrand.equals("XenServer") && prodVersion.equals("6.0.0")) @@ -438,7 +436,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (prodBrand.equals("XenServer") && prodVersion.equals("6.0.2")) return new XenServer602Resource(); - + if (prodBrand.equals("XenServer") && prodVersion.equals("6.1.0")) return new XenServer610Resource(); @@ -450,67 +448,67 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L return new XenServer56FP1Resource(); } } - + if (prodBrand.equals("XCP_Kronos")) { return new XcpOssResource(); } - + String msg = "Only support XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x; XenServer 5.6, XenServer 5.6 FP1, XenServer 5.6 SP2, Xenserver 6.0, 6.0.2, 6.1.0 but this one is " + prodBrand + " " + prodVersion; _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, dcId, podId, msg, msg); s_logger.debug(msg); throw new RuntimeException(msg); } - - protected void serverConfig() { + + protected void serverConfig() { String value = _params.get(Config.XenSetupMultipath.key()); _setupMultipath = Boolean.parseBoolean(value); } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); serverConfig(); - + _publicNic = _params.get(Config.XenPublicNetwork.key()); _privateNic = _params.get(Config.XenPrivateNetwork.key()); - + _storageNic1 = _params.get(Config.XenStorageNetwork1.key()); _storageNic2 = _params.get(Config.XenStorageNetwork2.key()); - + _guestNic = _params.get(Config.XenGuestNetwork.key()); - + String value = _params.get(Config.XapiWait.toString()); _wait = NumbersUtil.parseInt(value, Integer.parseInt(Config.XapiWait.getDefaultValue())); - + _instance = _params.get(Config.InstanceName.key()); - + value = _params.get(Config.XenSetupMultipath.key()); Boolean.parseBoolean(value); value = _params.get("xen.check.hvm"); _checkHvm = false; _connPool = XenServerConnectionPool.getInstance(); - + _agentMgr.registerForHostEvents(this, true, false, true); - + createXsToolsISO(); _resourceMgr.registerResourceStateAdapter(this.getClass().getSimpleName(), this); return true; } - + @Override public boolean matchHypervisor(String hypervisor) { if(hypervisor == null) return true; return Hypervisor.HypervisorType.XenServer.toString().equalsIgnoreCase(hypervisor); } - + @Override public Hypervisor.HypervisorType getHypervisorType() { return Hypervisor.HypervisorType.XenServer; } - + @Override public void postDiscovery(List hosts, long msId) throws DiscoveryException{ //do nothing @@ -535,7 +533,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L public boolean processCommands(long agentId, long seq, Command[] commands) { return false; } - + private void createXsToolsISO() { String isoName = "xs-tools.iso"; VMTemplateVO tmplt = _tmpltDao.findByTemplateName(isoName); @@ -558,17 +556,17 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L public void processConnect(com.cloud.host.Host agent, StartupCommand cmd, boolean forRebalance) throws ConnectionException { if (!(cmd instanceof StartupRoutingCommand )) { return; - } + } long agentId = agent.getId(); - + StartupRoutingCommand startup = (StartupRoutingCommand)cmd; if (startup.getHypervisorType() != HypervisorType.XenServer) { s_logger.debug("Not XenServer so moving on."); return; } - + HostVO host = _hostDao.findById(agentId); - + ClusterVO cluster = _clusterDao.findById(host.getClusterId()); if ( cluster.getGuid() == null) { cluster.setGuid(startup.getPool()); @@ -582,7 +580,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L Map details = startup.getHostDetails(); String prodBrand = details.get("product_brand").trim(); String prodVersion = details.get("product_version").trim(); - + if(prodBrand.equals("XCP") && (prodVersion.equals("1.0.0") || prodVersion.equals("1.1.0") || prodVersion.equals("5.6.100") || prodVersion.startsWith("1.4") || prodVersion.startsWith("1.6"))) { resource = XcpServerResource.class.getName(); } else if(prodBrand.equals("XenServer") && prodVersion.equals("5.6.0")) { @@ -603,7 +601,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L } else if (prodBrand.equals("XCP_Kronos")) { resource = XcpOssResource.class.getName(); } - + if( resource == null ){ String msg = "Only support XCP 1.0.0, 1.1.0, 1.4.x, 1.5 beta, 1.6.x; XenServer 5.6, 5.6 FP1, 5.6 SP2 and Xenserver 6.0 , 6.0.2, 6.1.0 but this one is " + prodBrand + " " + prodVersion; s_logger.debug(msg); @@ -617,13 +615,13 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L _hostDao.update(agentId, host); throw new HypervisorVersionChangedException(msg); } - - + + if (s_logger.isDebugEnabled()) { s_logger.debug("Setting up host " + agentId); } HostEnvironment env = new HostEnvironment(); - + SetupCommand setup = new SetupCommand(env); if (_setupMultipath) { setup.setMultipathOn(); @@ -631,7 +629,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (!host.isSetup()) { setup.setNeedSetup(true); } - + try { SetupAnswer answer = (SetupAnswer)_agentMgr.send(agentId, setup); if (answer != null && answer.getResult()) { @@ -699,7 +697,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (host.getType() != com.cloud.host.Host.Type.Routing || host.getHypervisorType() != HypervisorType.XenServer) { return null; } - + _resourceMgr.deleteRoutingHost(host, isForced, isForceDeleteStorage); if (host.getClusterId() != null) { List hosts = _resourceMgr.listAllUpAndEnabledHosts(com.cloud.host.Host.Type.Routing, host.getClusterId(), host.getPodId(), host.getDataCenterId()); @@ -708,7 +706,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L if (thost.getId() == host.getId()) { continue; } - + long thostId = thost.getId(); PoolEjectCommand eject = new PoolEjectCommand(host.getGuid()); Answer answer = _agentMgr.easySend(thostId, eject); @@ -728,10 +726,10 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L _alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, host.getDataCenterId(), host.getPodId(), "Unable to eject host " + host.getGuid(), msg); } } - + return new DeleteHostAnswer(true); } - + @Override public boolean stop() { _resourceMgr.unregisterResourceStateAdapter(this.getClass().getSimpleName()); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 4debdc3b73f..aca8afc66c3 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -33,7 +33,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; @@ -42,7 +41,6 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; -import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -56,7 +54,6 @@ import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; -import com.cloud.configuration.Resource.ResourceType; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.HostVO; @@ -64,9 +61,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; @@ -74,7 +69,6 @@ import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; @@ -97,8 +91,6 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { @Inject VMTemplateDao templateDao; @Inject DownloadMonitor _downloadMonitor; - @Inject - VMTemplateHostDao _vmTemplateHostDao; @Inject VolumeDao volumeDao; @Inject VolumeHostDao volumeHostDao; @Inject HostDao hostDao; @@ -176,7 +168,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { AsyncCallbackDispatcher.create(this); caller.setContext(context); caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 366d2e5250c..c7d2475c52e 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -67,7 +67,6 @@ import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; @@ -91,8 +90,6 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { VMTemplateDao templateDao; @Inject DownloadMonitor _downloadMonitor; @Inject - VMTemplateHostDao _vmTemplateHostDao; - @Inject ImageStoreDetailsDao _imageStoreDetailsDao; @Inject VolumeDao volumeDao; @Inject VolumeHostDao volumeHostDao; diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 149361602a4..4c664d981fc 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -67,7 +67,6 @@ import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; @@ -91,8 +90,6 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { VMTemplateDao templateDao; @Inject DownloadMonitor _downloadMonitor; @Inject - VMTemplateHostDao _vmTemplateHostDao; - @Inject ImageStoreDetailsDao _imageStoreDetailsDao; @Inject VolumeDao volumeDao; @Inject VolumeHostDao volumeHostDao; diff --git a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java index 29e1be9547c..af4e4110913 100755 --- a/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java +++ b/server/src/com/cloud/agent/manager/allocator/impl/UserConcentratedAllocator.java @@ -70,8 +70,6 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat @Inject HostPodDao _podDao; @Inject - VMTemplateHostDao _templateHostDao; - @Inject VMTemplatePoolDao _templatePoolDao; @Inject ServiceOfferingDao _offeringDao; @@ -87,7 +85,8 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat private int _secondsToSkipDestroyedVMs = 0; @Override - public Pair allocateTo(VirtualMachineTemplate template, ServiceOfferingVO offering, DataCenterVO zone, long accountId, Set avoids) { + public Pair allocateTo(VirtualMachineTemplate template, ServiceOfferingVO offering, DataCenterVO zone, long accountId, + Set avoids) { long zoneId = zone.getId(); List podsInZone = _podDao.listByDataCenterId(zoneId); @@ -107,23 +106,28 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat } if (offering != null) { - // test for enough memory in the pod (make sure to check for enough memory for the service offering, plus + // test for enough memory in the pod (make sure to check for + // enough memory for the service offering, plus // some extra padding for xen overhead long[] hostCandiates = new long[1]; - boolean enoughCapacity = dataCenterAndPodHasEnoughCapacity(zoneId, podId, (offering.getRamSize()) * 1024L * 1024L, CapacityVO.CAPACITY_TYPE_MEMORY, hostCandiates); + boolean enoughCapacity = dataCenterAndPodHasEnoughCapacity(zoneId, podId, (offering.getRamSize()) * 1024L * 1024L, + CapacityVO.CAPACITY_TYPE_MEMORY, hostCandiates); if (!enoughCapacity) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Not enough RAM available in zone/pod to allocate storage for user VM (zone: " + zoneId + ", pod: " + podId + ")"); + s_logger.debug("Not enough RAM available in zone/pod to allocate storage for user VM (zone: " + zoneId + ", pod: " + + podId + ")"); } continue; } // test for enough CPU in the pod - enoughCapacity = dataCenterAndPodHasEnoughCapacity(zoneId, podId, (offering.getCpu() * offering.getSpeed()), CapacityVO.CAPACITY_TYPE_CPU, hostCandiates); + enoughCapacity = dataCenterAndPodHasEnoughCapacity(zoneId, podId, (offering.getCpu() * offering.getSpeed()), + CapacityVO.CAPACITY_TYPE_CPU, hostCandiates); if (!enoughCapacity) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Not enough cpu available in zone/pod to allocate storage for user VM (zone: " + zoneId + ", pod: " + podId + ")"); + s_logger.debug("Not enough cpu available in zone/pod to allocate storage for user VM (zone: " + zoneId + ", pod: " + + podId + ")"); } continue; } @@ -207,7 +211,8 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat } if (vm.getState() == State.Stopped || vm.getState() == State.Destroyed) { - // for Stopped/Destroyed VMs, we will skip counting it if it hasn't been used for a while + // for Stopped/Destroyed VMs, we will skip counting it if it hasn't + // been used for a while int secondsToSkipVMs = _secondsToSkipStoppedVMs; if (vm.getState() == State.Destroyed) { @@ -217,8 +222,9 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat long millisecondsSinceLastUpdate = DateUtil.currentGMTTime().getTime() - vm.getUpdateTime().getTime(); if (millisecondsSinceLastUpdate > secondsToSkipVMs * 1000L) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Skip counting " + vm.getState().toString() + " vm " + vm.getInstanceName() + " in capacity allocation as it has been " + vm.getState().toString().toLowerCase() - + " for " + millisecondsSinceLastUpdate / 60000 + " minutes"); + s_logger.debug("Skip counting " + vm.getState().toString() + " vm " + vm.getInstanceName() + + " in capacity allocation as it has been " + vm.getState().toString().toLowerCase() + " for " + + millisecondsSinceLastUpdate / 60000 + " minutes"); } return true; } @@ -228,11 +234,12 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat } /** - * + * * @param hostId * Host id to calculate against * @param capacityType - * CapacityVO.CAPACITY_TYPE_MEMORY or CapacityVO.CAPACITY_TYPE_CPU + * CapacityVO.CAPACITY_TYPE_MEMORY or + * CapacityVO.CAPACITY_TYPE_CPU * @return */ private long calcHostAllocatedCpuMemoryCapacity(long hostId, short capacityType) { @@ -253,21 +260,23 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat if (userVm == null) { continue; } - } - + } + so = _offeringDao.findById(vm.getServiceOfferingId()); if (capacityType == CapacityVO.CAPACITY_TYPE_MEMORY) { usedCapacity += so.getRamSize() * 1024L * 1024L; if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + ", currently counted: " + usedCapacity + " Bytes"); + s_logger.debug("Counting memory capacity used by vm: " + vm.getId() + ", size: " + so.getRamSize() + "MB, host: " + hostId + + ", currently counted: " + usedCapacity + " Bytes"); } } else if (capacityType == CapacityVO.CAPACITY_TYPE_CPU) { usedCapacity += so.getCpu() * so.getSpeed(); if (s_logger.isDebugEnabled()) { - s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + ", currently counted: " + usedCapacity + " Bytes"); + s_logger.debug("Counting cpu capacity used by vm: " + vm.getId() + ", cpu: " + so.getCpu() + ", speed: " + so.getSpeed() + + ", currently counted: " + usedCapacity + " Bytes"); } } } @@ -281,7 +290,7 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat * List thvoList = _templateHostDao.listByTemplateStatus(templateId, dcId, podId, Status.DOWNLOADED); * List tpvoList = _templatePoolDao.listByTemplateStatus(templateId, dcId, podId, * Status.DOWNLOADED); - * + * * if (thvoList != null && thvoList.size() > 0) { if (s_logger.isDebugEnabled()) { s_logger.debug("Found " + * thvoList.size() + " storage hosts in pod " + podId + " with template " + templateId); } return true; } else if * (tpvoList != null && tpvoList.size() > 0) { if (s_logger.isDebugEnabled()) { s_logger.debug("Found " + @@ -304,7 +313,8 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat public boolean configure(String name, Map params) throws ConfigurationException { Map configs = _configDao.getConfiguration("management-server", params); String stoppedValue = configs.get("vm.resource.release.interval"); - // String destroyedValue = configs.get("capacity.skipcounting.destroyed.hours"); + // String destroyedValue = + // configs.get("capacity.skipcounting.destroyed.hours"); String destroyedValue = null; _secondsToSkipStoppedVMs = NumbersUtil.parseInt(stoppedValue, 86400); _secondsToSkipDestroyedVMs = NumbersUtil.parseInt(destroyedValue, 0); @@ -312,19 +322,19 @@ public class UserConcentratedAllocator extends AdapterBase implements PodAllocat /* * ComponentLocator locator = ComponentLocator.getCurrentLocator(); _vmDao = locator.getDao(UserVmDao.class); if (_vmDao * == null) { throw new ConfigurationException("Unable to find UserVMDao."); } - * + * * _volumeDao = locator.getDao(VolumeDao.class); if (_volumeDao == null) { throw new * ConfigurationException("Unable to find VolumeDao."); } - * + * * _templateHostDao = locator.getDao(VMTemplateHostDao.class); if (_templateHostDao == null) { throw new * ConfigurationException("Unable to get template host dao."); } - * + * * _templatePoolDao = locator.getDao(VMTemplatePoolDao.class); if (_templatePoolDao == null) { throw new * ConfigurationException("Unable to get template pool dao."); } - * + * * _podDao = locator.getDao(HostPodDao.class); if (_podDao == null) { throw new * ConfigurationException("Unable to find HostPodDao."); } - * + * * _capacityDao = locator.getDao(CapacityDao.class); if (_capacityDao == null) { throw new * ConfigurationException("Unable to retrieve " + CapacityDao.class); } */ diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 41082b76d67..ecac9ddbe12 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -320,7 +320,6 @@ public class ApiDBUtils { static PrimaryDataStoreDao _storagePoolDao; static VMTemplateDao _templateDao; static VMTemplateDetailsDao _templateDetailsDao; - static VMTemplateHostDao _templateHostDao; static VMTemplateSwiftDao _templateSwiftDao; static VMTemplateS3Dao _templateS3Dao; static UploadDao _uploadDao; @@ -426,7 +425,6 @@ public class ApiDBUtils { @Inject private PrimaryDataStoreDao storagePoolDao; @Inject private VMTemplateDao templateDao; @Inject private VMTemplateDetailsDao templateDetailsDao; - @Inject private VMTemplateHostDao templateHostDao; @Inject private VMTemplateSwiftDao templateSwiftDao; @Inject private VMTemplateS3Dao templateS3Dao; @Inject private UploadDao uploadDao; @@ -530,7 +528,6 @@ public class ApiDBUtils { _storagePoolDao = storagePoolDao; _templateDao = templateDao; _templateDetailsDao = templateDetailsDao; - _templateHostDao = templateHostDao; _templateSwiftDao = templateSwiftDao; _templateS3Dao = templateS3Dao; _uploadDao = uploadDao; @@ -933,18 +930,6 @@ public class ApiDBUtils { return _storageMgr.getHypervisorTypeFromFormat(format); } - public static List listTemplateHostBy(long templateId, Long zoneId, boolean readyOnly) { - if (zoneId != null) { - VMTemplateVO vmTemplate = findTemplateById(templateId); - if (vmTemplate.getHypervisorType() == HypervisorType.BareMetal) { - return _templateHostDao.listByTemplateId(templateId); - } else { - return _templateHostDao.listByZoneTemplate(zoneId, templateId, readyOnly); - } - } else { - return _templateHostDao.listByOnlyTemplateId(templateId); - } - } public static List listUserStatsBy(Long accountId) { return _userStatsDao.listBy(accountId); diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index fa489ff7a2f..1687f1b2957 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -5,7 +5,7 @@ // 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, @@ -33,6 +33,8 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -112,12 +114,10 @@ import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.servlet.ConsoleProxyServlet; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolStatus; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; @@ -127,7 +127,6 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.GlobalLock; @@ -203,7 +202,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy @Inject private VMInstanceDao _instanceDao; @Inject - private VMTemplateHostDao _vmTemplateHostDao; + private TemplateDataStoreDao _vmTemplateStoreDao; @Inject private AgentManager _agentMgr; @Inject @@ -287,7 +286,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy * "PWpfKR3ISI5yXB0vRNAL6Vet5zbTcUZhKDVtNSbis3UEsGYH8NorEC2z2cpjGQJANhJi9Ow6c5Mh\n" * + "/DURBUn+1l5pyCKrZnDbvaALSLATLvjmFTuGjoHszy2OeKnOZmEqExWnKKE/VYuPyhy6V7i3TwJA\n" + * "f8skDgtPK0OsBCa6IljPaHoWBjPc4kFkSTSS1d56hUcWSikTmiuKdLyBb85AADSZYsvHWrte4opN\n" + "dhNukMJuRA==\n"; - * + * * private final String certContent = "-----BEGIN CERTIFICATE-----\n" + * "MIIE3jCCA8agAwIBAgIFAqv56tIwDQYJKoZIhvcNAQEFBQAwgcoxCzAJBgNVBAYT\n" * + "AlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYD\n" + @@ -668,7 +667,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy if(proxy.getActiveSession() >= _capacityPerProxy){ it.remove(); } - } + } if (s_logger.isTraceEnabled()) { s_logger.trace("Running proxy pool size : " + runningList.size()); for (ConsoleProxyVO proxy : runningList) { @@ -961,7 +960,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy authenticationAnswer.setReauthenticating(true); s_logger.info("Re-authentication request, ask host " + vm.getHostId() + " for new console info"); - GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new + GetVncPortAnswer answer = (GetVncPortAnswer) _agentMgr.easySend(vm.getHostId(), new GetVncPortCommand(vm.getId(), vm.getInstanceName())); if (answer != null && answer.getResult()) { @@ -1175,15 +1174,10 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy ZoneHostInfo zoneHostInfo = zoneHostInfoMap.get(dataCenterId); if (zoneHostInfo != null && isZoneHostReady(zoneHostInfo)) { VMTemplateVO template = _templateDao.findSystemVMTemplate(dataCenterId); - HostVO secondaryStorageHost = this.templateMgr.getSecondaryStorageHost(dataCenterId); - boolean templateReady = false; + TemplateDataStoreVO templateHostRef = this._vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dataCenterId, + Status.DOWNLOADED); - if (template != null && secondaryStorageHost != null) { - VMTemplateHostVO templateHostRef = _vmTemplateHostDao.findByHostTemplate(secondaryStorageHost.getId(), template.getId()); - templateReady = (templateHostRef != null) && (templateHostRef.getDownloadState() == Status.DOWNLOADED); - } - - if (templateReady) { + if (templateHostRef != null) { List> l = _consoleProxyDao.getDatacenterStoragePoolHostInfo(dataCenterId, _use_lvm); if (l != null && l.size() > 0 && l.get(0).second().intValue() > 0) { return true; @@ -1196,11 +1190,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy if (s_logger.isDebugEnabled()) { if (template == null) { s_logger.debug("Zone host is ready, but console proxy template is null"); - } else if (secondaryStorageHost != null) { - s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage: " + secondaryStorageHost.getId()); - } else { - s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); - } + } else { + s_logger.debug("Zone host is ready, but console proxy template: " + template.getId() + " is not ready on secondary storage."); + } } } } @@ -1397,7 +1389,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy //expunge the vm boolean result = _itMgr.expunge(proxy, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount()); if (result) { - HostVO host = _hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), + HostVO host = _hostDao.findByTypeNameAndZoneId(proxy.getDataCenterId(), proxy.getHostName(), Host.Type.ConsoleProxy); if (host != null) { s_logger.debug("Removing host entry for proxy id=" + vmId); diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index e8805ae8910..49c3af1853b 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -30,6 +30,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -140,9 +142,9 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim @Inject private ServiceOfferingDao _serviceOfferingDao; @Inject - private VMTemplateHostDao _vmTemplateHostDao; + private TemplateDataStoreDao _vmTemplateStoreDao; - protected GenericSearchBuilder templateSizeSearch; + protected GenericSearchBuilder templateSizeSearch; protected SearchBuilder ResourceCountSearch; ScheduledExecutorService _rcExecutor; @@ -172,7 +174,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim ResourceCountSearch.and("domainId", ResourceCountSearch.entity().getDomainId(), SearchCriteria.Op.EQ); ResourceCountSearch.done(); - templateSizeSearch = _vmTemplateHostDao.createSearchBuilder(SumCount.class); + templateSizeSearch = _vmTemplateStoreDao.createSearchBuilder(SumCount.class); templateSizeSearch.select("sum", Func.SUM, templateSizeSearch.entity().getSize()); templateSizeSearch.and("downloadState", templateSizeSearch.entity().getDownloadState(), Op.EQ); templateSizeSearch.and("destroyed", templateSizeSearch.entity().getDestroyed(), Op.EQ); @@ -198,7 +200,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim projectResourceLimitMap.put(Resource.ResourceType.memory, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectMemory.key()))); projectResourceLimitMap.put(Resource.ResourceType.primary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectPrimaryStorage.key()))); projectResourceLimitMap.put(Resource.ResourceType.secondary_storage, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectSecondaryStorage.key()))); - + accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key()))); accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key()))); accountResourceLimitMap.put(Resource.ResourceType.template, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountTemplates.key()))); @@ -898,7 +900,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim sc.setParameters("downloadState", Status.DOWNLOADED); sc.setParameters("destroyed", false); sc.setJoinParameters("templates", "accountId", accountId); - List templates = _vmTemplateHostDao.customSearch(sc, null); + List templates = _vmTemplateStoreDao.customSearch(sc, null); if (templates != null) { totalTemplatesSize = templates.get(0).sum; } diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 0495255a84c..3f07cba1b75 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -47,7 +47,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; -import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import com.cloud.agent.manager.Commands; @@ -66,12 +65,10 @@ import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Type; import com.cloud.storage.DataStoreRole; import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ManagerBase; @@ -92,8 +89,6 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { static final Logger s_logger = Logger.getLogger(UploadMonitorImpl.class); - @Inject - VMTemplateHostDao _vmTemplateHostDao; @Inject UploadDao _uploadDao; @Inject diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 24bce8b1705..f1b32ed271c 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -173,7 +173,6 @@ import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateDetailsDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; @@ -249,8 +248,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use @Inject protected VMTemplateDetailsDao _templateDetailsDao = null; @Inject - protected VMTemplateHostDao _templateHostDao = null; - @Inject protected VMTemplateZoneDao _templateZoneDao = null; @Inject protected DomainDao _domainDao = null; @@ -367,7 +364,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use VpcManager _vpcMgr; @Inject TemplateManager templateMgr; - @Inject + @Inject protected GuestOSCategoryDao _guestOSCategoryDao; @Inject UsageEventDao _usageEventDao; @@ -682,7 +679,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use try { VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid()); - status = vmEntity.stop(new Long(userId).toString()); + status = vmEntity.stop(new Long(userId).toString()); } catch (ResourceUnavailableException e) { s_logger.debug("Unable to stop due to ", e); status = false; @@ -2032,7 +2029,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use isSecurityGroupEnabledNetworkUsed = true; } else { - // Verify that all the networks are Shared/Guest; can't create combination of SG enabled and disabled networks + // Verify that all the networks are Shared/Guest; can't create combination of SG enabled and disabled networks for (Long networkId : networkIdList) { NetworkVO network = _networkDao.findById(networkId); @@ -2048,7 +2045,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use } isSecurityGroupEnabledNetworkUsed = true; - } + } if (!(network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared)) { throw new InvalidParameterValueException("Can specify only Shared Guest networks when" + @@ -2452,7 +2449,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use // * verify that there are no duplicates if (hostNames.contains(hostName)) { throw new InvalidParameterValueException("The vm with hostName " + hostName - + " already exists in the network domain: " + ntwkDomain + "; network=" + + " already exists in the network domain: " + ntwkDomain + "; network=" + _networkModel.getNetwork(ntwkId)); } } @@ -2515,7 +2512,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use List computeTags = new ArrayList(); computeTags.add(offering.getHostTag()); - List rootDiskTags = new ArrayList(); + List rootDiskTags = new ArrayList(); rootDiskTags.add(offering.getTags()); if(isIso){ @@ -2834,7 +2831,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use try { VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid()); - vmEntity.stop(new Long(userId).toString()); + vmEntity.stop(new Long(userId).toString()); } catch (ResourceUnavailableException e) { throw new CloudRuntimeException( "Unable to contact the agent to stop the virtual machine " @@ -3049,7 +3046,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use try { VirtualMachineEntity vmEntity = _orchSrvc.getVirtualMachine(vm.getUuid()); - status = vmEntity.destroy(new Long(userId).toString()); + status = vmEntity.destroy(new Long(userId).toString()); } catch (CloudException e) { CloudRuntimeException ex = new CloudRuntimeException( "Unable to destroy with specified vmId", e); From 0cfef3aa4e807f15408d3ed70d13bc0e96691ff0 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 23 Apr 2013 17:51:54 -0700 Subject: [PATCH 056/303] Remove almost all VMTemplateHostDao references except S3Manager and SwiftManager. --- .../api/storage/DataStoreManager.java | 1 + .../motion/AncientDataMotionStrategy.java | 37 ++++++++-------- .../datastore/DataStoreManagerImpl.java | 13 ++++++ .../com/cloud/template/TemplateManager.java | 9 ---- .../cloud/template/TemplateManagerImpl.java | 42 ++++--------------- 5 files changed, 39 insertions(+), 63 deletions(-) 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 096a1fd1497..4dca1ceab10 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 @@ -29,6 +29,7 @@ public interface DataStoreManager { public DataStore getPrimaryDataStore(long storeId); public DataStore getDataStore(String uuid, DataStoreRole role); public List getImageStoresByScope(ZoneScope scope); + public DataStore getImageStore(long zoneId); public List getImageStoresByProvider(String provider); public List getImageCacheStores(Scope scope); public DataStore registerDataStore(Map params, String providerUuid); 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 index b0229d88640..826a3c77190 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -27,6 +27,7 @@ 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; @@ -38,6 +39,8 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -124,7 +127,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @Inject DataStoreManager dataStoreMgr; @Inject - VMTemplateHostDao templateHostDao; + TemplateDataStoreDao templateStoreDao; @Inject DiskOfferingDao diskOfferingDao; @Inject VMTemplatePoolDao templatePoolDao; @Inject @@ -319,7 +322,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected Answer cloneVolume(DataObject template, DataObject volume) { CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0); StoragePool pool = (StoragePool)volume.getDataStore(); - + try { Answer answer = storageMgr.sendToPool(pool, null, cmd); return answer; @@ -399,7 +402,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { answer = copyFromSnapshot(srcData, destData); } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.TEMPLATE) { - answer = createTemplateFromSnashot(srcData, destData); + answer = createTemplateFromSnapshot(srcData, destData); } else if (srcData.getType() == DataObjectType.VOLUME && destData.getType() == DataObjectType.TEMPLATE) { answer = createTemplateFromVolume(srcData, destData); @@ -425,7 +428,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } @DB - protected Answer createTemplateFromSnashot(DataObject srcData, + protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destData) { long snapshotId = srcData.getId(); SnapshotVO snapshot = snapshotDao.findById(snapshotId); @@ -434,8 +437,11 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { + srcData.getId()); } Long zoneId = snapshot.getDataCenterId(); + DataStore secStore = destData.getDataStore(); + /* HostVO secondaryStorageHost = this.templateMgr .getSecondaryStorageHost(zoneId); + */ String secondaryStorageURL = snapshotMgr .getSecondaryStorageURL(snapshot); VMTemplateVO template = this.templateDao.findById(destData.getId()); @@ -536,13 +542,12 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { origTemplateInstallPath, template.getId(), name, _createprivatetemplatefromsnapshotwait); - return sendCommand(cmd, pool, template.getId(), dcId, - secondaryStorageHost.getId()); + return sendCommand(cmd, pool, template.getId(), dcId, secStore); } @DB protected Answer sendCommand(Command cmd, StoragePool pool, - long templateId, long zoneId, long hostId) { + long templateId, long zoneId, DataStore secStore) { CreatePrivateTemplateAnswer answer = null; try { @@ -573,7 +578,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } String checkSum = this.templateMgr - .getChecksum(hostId, answer.getPath()); + .getChecksum(secStore, answer.getPath()); Transaction txn = Transaction.currentTxn(); @@ -584,7 +589,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { // add template zone ref for this template templateDao.addTemplateToZone(privateTemplate, zoneId); - VMTemplateHostVO templateHostVO = new VMTemplateHostVO(hostId, + TemplateDataStoreVO templateHostVO = new TemplateDataStoreVO(secStore.getId(), privateTemplate.getId()); templateHostVO.setDownloadPercent(100); templateHostVO.setDownloadState(Status.DOWNLOADED); @@ -592,7 +597,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { templateHostVO.setLastUpdated(new Date()); templateHostVO.setSize(answer.getVirtualSize()); templateHostVO.setPhysicalSize(answer.getphysicalSize()); - templateHostDao.persist(templateHostVO); + templateStoreDao.persist(templateHostVO); txn.close(); return answer; } @@ -609,13 +614,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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(); + DataStore secStore = destObj.getDataStore(); + String secondaryStorageURL = secStore.getUri(); VMTemplateVO template = this.templateDao.findById(destObj.getId()); StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore( volume.getPoolId(), DataStoreRole.Primary); @@ -630,8 +630,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { template.getName(), template.getUniqueName(), volume.getPath(), vmName, _createprivatetemplatefromvolumewait); - return sendCommand(cmd, pool, template.getId(), zoneId, - secondaryStorageHost.getId()); + return sendCommand(cmd, pool, template.getId(), zoneId, secStore); } private HostVO getSecHost(long volumeId, long dcId) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index fb1460400b9..0ea653b5847 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -33,6 +33,8 @@ import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; import com.cloud.utils.exception.CloudRuntimeException; +import edu.emory.mathcs.backport.java.util.Collections; + @Component public class DataStoreManagerImpl implements DataStoreManager { @Inject @@ -74,6 +76,17 @@ public class DataStoreManagerImpl implements DataStoreManager { } + + @Override + public DataStore getImageStore(long zoneId) { + List stores = getImageStoresByScope(new ZoneScope(zoneId)); + if (stores == null || stores.size() == 0) { + return null; + } + Collections.shuffle(stores); + return stores.get(0); + } + @Override public List getImageStoresByProvider(String provider) { return imageDataStoreMgr.listImageStoreByProvider(provider); diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index f44c0a7535b..dedb0b480d6 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -18,8 +18,6 @@ package com.cloud.template; import java.util.List; -import org.apache.cloudstack.api.command.user.iso.UpdateIsoCmd; -import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -100,13 +98,8 @@ public interface TemplateManager extends TemplateApiService{ String getSecondaryStorageURL(long zoneId); - //HostVO getSecondaryStorageHost(long zoneId, long tmpltId); - DataStore getImageStore(long zoneId, long tmpltId); - // VMTemplateHostVO getTemplateHostRef(long zoneId, long tmpltId, - // boolean readyOnly); - HostVO getSecondaryStorageHost(long zoneId); List getSecondaryStorageHosts(long zoneId); @@ -115,8 +108,6 @@ public interface TemplateManager extends TemplateApiService{ DataStore getImageStore(String storeUuid, Long zoneId); - String getChecksum(Long hostId, String templatePath); - String getChecksum(DataStore store, String templatePath); List getImageStoreByTemplate(long templateId, Long zoneId); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index a9a43baf002..abe467a98af 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -106,7 +106,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; -import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; @@ -647,24 +646,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } - @Override - public String getChecksum(Long hostId, String templatePath) { - HostVO ssHost = _hostDao.findById(hostId); - Host.Type type = ssHost.getType(); - if (type != Host.Type.SecondaryStorage - && type != Host.Type.LocalSecondaryStorage) { - return null; - } - String secUrl = ssHost.getStorageUrl(); - Answer answer; - answer = _agentMgr.sendToSecStorage(ssHost, new ComputeChecksumCommand( - secUrl, templatePath)); - if (answer != null && answer.getResult()) { - return answer.getDetails(); - } - return null; - } - @Override public String getChecksum(DataStore store, String templatePath) { @@ -1741,35 +1722,26 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public String getSecondaryStorageURL(long zoneId) { - // Determine the secondary storage URL - HostVO secondaryStorageHost = getSecondaryStorageHost(zoneId); - - if (secondaryStorageHost == null) { + DataStore secStore = this._dataStoreMgr.getImageStore(zoneId); + if (secStore == null) { return null; } - return secondaryStorageHost.getStorageUrl(); + return secStore.getUri(); } // get the image store where a template in a given zone is downloaded to, just pick one is enough. @Override public DataStore getImageStore(long zoneId, long tmpltId) { - List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); - if (stores == null || stores.size() == 0) { - return null; - } - for (DataStore host : stores) { - List tmpltStore = this._tmplStoreDao.listByTemplateStoreDownloadStatus( - tmpltId, host.getId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if ( tmpltStore != null && tmpltStore.size() > 0 ){ - return host; - } + TemplateDataStoreVO tmpltStore = this._tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (tmpltStore != null){ + return this._dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image); } + return null; } - @Override public HostVO getSecondaryStorageHost(long zoneId) { List hosts = _ssvmMgr From 792fc471a20b9378555e984d977070edd0d45e14 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 11:11:58 -0700 Subject: [PATCH 057/303] Remove VolumeHostDao references from codebase. --- .../motion/AncientDataMotionStrategy.java | 27 +-- .../CloudStackImageStoreDriverImpl.java | 29 ++-- .../driver/S3ImageStoreDriverImpl.java | 26 +-- .../driver/SwiftImageStoreDriverImpl.java | 27 +-- server/src/com/cloud/api/ApiDBUtils.java | 7 - .../com/cloud/storage/StorageManagerImpl.java | 155 ++++++------------ .../com/cloud/storage/VolumeManagerImpl.java | 19 +-- .../storage/download/DownloadMonitorImpl.java | 4 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 2 - 9 files changed, 114 insertions(+), 182 deletions(-) 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 index 826a3c77190..affe0308dba 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -41,6 +41,8 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -55,13 +57,8 @@ 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.storage.PrimaryStorageDownloadAnswer; -import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; 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; @@ -69,25 +66,19 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; -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; @@ -96,7 +87,6 @@ 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 { @@ -107,7 +97,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @Inject TemplateManager templateMgr; @Inject - VolumeHostDao volumeHostDao; + VolumeDataStoreDao volumeStoreDao; @Inject HostDao hostDao; @Inject @@ -151,15 +141,14 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - VolumeHostVO volumeHostVO = volumeHostDao.findByVolumeId(srcData + VolumeDataStoreVO volumeStoreVO = volumeStoreDao.findByVolume(srcData .getId()); - HostVO secStorage = hostDao.findById(volumeHostVO.getHostId()); - String secondaryStorageURL = secStorage.getStorageUrl(); - String[] volumePath = volumeHostVO.getInstallPath().split("/"); + DataStore srcStore = srcData.getDataStore(); + String[] volumePath = volumeStoreVO.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, + volumeUUID, destPool, srcStore.getUri(), false, _copyvolumewait); CopyVolumeAnswer cvAnswer = null; String errMsg = null; @@ -186,7 +175,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { vol.setPodId(destPool.getPodId()); this.volDao.update(vol.getId(), vol); - volumeHostDao.remove(volumeHostVO.getId()); + volumeStoreDao.remove(volumeStoreVO.getId()); txn.commit(); return cvAnswer; } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index aca8afc66c3..4f8096c8c1a 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; @@ -38,6 +39,8 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -56,7 +59,6 @@ import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; -import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.RegisterVolumePayload; @@ -65,13 +67,11 @@ import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; @@ -92,7 +92,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { VMTemplateDao templateDao; @Inject DownloadMonitor _downloadMonitor; @Inject VolumeDao volumeDao; - @Inject VolumeHostDao volumeHostDao; + @Inject VolumeDataStoreDao _volumeStoreDao; @Inject HostDao hostDao; @Inject SnapshotDao snapshotDao; @Inject AgentManager agentMgr; @@ -109,6 +109,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { private AgentManager _agentMgr; @Inject TemplateDataStoreDao _templateStoreDao; @Inject EndPointSelector _epSelector; + @Inject DataStoreManager _dataStoreMgr; @Override @@ -223,35 +224,35 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub VolumeVO vol = volumeDao.findById(data.getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Expunging " + vol); } // Find out if the volume is present on secondary storage - VolumeHostVO volumeHost = volumeHostDao.findByVolumeId(vol.getId()); - if (volumeHost != null) { - if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - HostVO ssHost = hostDao.findById(volumeHost.getHostId()); + VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId()); + if (volumeStore != null) { + if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); + EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - ssHost.getStorageUrl(), volumeHost.getInstallPath()); - Answer answer = agentMgr.sendToSecStorage(ssHost, dtCommand); + store.getUri(), volumeStore.getInstallPath()); + Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " - + volumeHost + + volumeStore + " due to " + ((answer == null) ? "answer is null" : answer .getDetails())); return; } - } else if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); throw new CloudRuntimeException( "Please specify a volume that is not currently being uploaded."); } - volumeHostDao.remove(volumeHost.getId()); + _volumeStoreDao.remove(volumeStore.getId()); volumeDao.remove(vol.getId()); CommandResult result = new CommandResult(); callback.complete(result); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index c7d2475c52e..3bbbb70e7de 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; @@ -39,6 +40,8 @@ import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -59,6 +62,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; @@ -92,7 +96,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { @Inject ImageStoreDetailsDao _imageStoreDetailsDao; @Inject VolumeDao volumeDao; - @Inject VolumeHostDao volumeHostDao; + @Inject VolumeDataStoreDao _volumeStoreDao; @Inject HostDao hostDao; @Inject SnapshotDao snapshotDao; @Inject AgentManager agentMgr; @@ -109,6 +113,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { private AgentManager _agentMgr; @Inject TemplateDataStoreDao _templateStoreDao; @Inject EndPointSelector _epSelector; + @Inject DataStoreManager _dataStoreMgr; @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -183,28 +188,29 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } // Find out if the volume is present on secondary storage - VolumeHostVO volumeHost = volumeHostDao.findByVolumeId(vol.getId()); - if (volumeHost != null) { - if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - HostVO ssHost = hostDao.findById(volumeHost.getHostId()); + VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId()); + if (volumeStore != null) { + if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); + EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - ssHost.getStorageUrl(), volumeHost.getInstallPath()); - Answer answer = agentMgr.sendToSecStorage(ssHost, dtCommand); + store.getUri(), volumeStore.getInstallPath()); + Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " - + volumeHost + + volumeStore + " due to " + ((answer == null) ? "answer is null" : answer .getDetails())); return; } - } else if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); throw new CloudRuntimeException( "Please specify a volume that is not currently being uploaded."); } - volumeHostDao.remove(volumeHost.getId()); + _volumeStoreDao.remove(volumeStore.getId()); volumeDao.remove(vol.getId()); CommandResult result = new CommandResult(); callback.complete(result); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 4c664d981fc..9ec73e65a5c 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; @@ -39,6 +40,8 @@ import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -59,6 +62,7 @@ import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; @@ -92,7 +96,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { @Inject ImageStoreDetailsDao _imageStoreDetailsDao; @Inject VolumeDao volumeDao; - @Inject VolumeHostDao volumeHostDao; + @Inject VolumeDataStoreDao _volumeStoreDao; @Inject HostDao hostDao; @Inject SnapshotDao snapshotDao; @Inject AgentManager agentMgr; @@ -109,6 +113,8 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { private AgentManager _agentMgr; @Inject TemplateDataStoreDao _templateStoreDao; @Inject EndPointSelector _epSelector; + @Inject DataStoreManager _dataStoreMgr; + @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -176,28 +182,29 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } // Find out if the volume is present on secondary storage - VolumeHostVO volumeHost = volumeHostDao.findByVolumeId(vol.getId()); - if (volumeHost != null) { - if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - HostVO ssHost = hostDao.findById(volumeHost.getHostId()); + VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId()); + if (volumeStore != null) { + if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); + EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - ssHost.getStorageUrl(), volumeHost.getInstallPath()); - Answer answer = agentMgr.sendToSecStorage(ssHost, dtCommand); + store.getUri(), volumeStore.getInstallPath()); + Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " - + volumeHost + + volumeStore + " due to " + ((answer == null) ? "answer is null" : answer .getDetails())); return; } - } else if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); throw new CloudRuntimeException( "Please specify a volume that is not currently being uploaded."); } - volumeHostDao.remove(volumeHost.getId()); + _volumeStoreDao.remove(volumeStore.getId()); volumeDao.remove(vol.getId()); CommandResult result = new CommandResult(); callback.complete(result); diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index ecac9ddbe12..df6c62545e0 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -331,7 +331,6 @@ public class ApiDBUtils { static VolumeDao _volumeDao; static Site2SiteVpnGatewayDao _site2SiteVpnGatewayDao; static Site2SiteCustomerGatewayDao _site2SiteCustomerGatewayDao; - static VolumeHostDao _volumeHostDao; static DataCenterDao _zoneDao; static NetworkOfferingDao _networkOfferingDao; static NetworkDao _networkDao; @@ -436,7 +435,6 @@ public class ApiDBUtils { @Inject private VolumeDao volumeDao; @Inject private Site2SiteVpnGatewayDao site2SiteVpnGatewayDao; @Inject private Site2SiteCustomerGatewayDao site2SiteCustomerGatewayDao; - @Inject private VolumeHostDao volumeHostDao; @Inject private DataCenterDao zoneDao; @Inject private NetworkOfferingDao networkOfferingDao; @Inject private NetworkDao networkDao; @@ -539,7 +537,6 @@ public class ApiDBUtils { _volumeDao = volumeDao; _site2SiteVpnGatewayDao = site2SiteVpnGatewayDao; _site2SiteCustomerGatewayDao = site2SiteCustomerGatewayDao; - _volumeHostDao = volumeHostDao; _zoneDao = zoneDao; _securityGroupDao = securityGroupDao; _securityGroupJoinDao = securityGroupJoinDao; @@ -865,10 +862,6 @@ public class ApiDBUtils { return template; } - public static VolumeHostVO findVolumeHostRef(long volumeId, long zoneId) { - return _volumeHostDao.findVolumeByZone(volumeId, zoneId); - } - public static VMTemplateSwiftVO findTemplateSwiftRef(long templateId) { return _templateSwiftDao.findOneByTemplateId(templateId); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index b91c87ec6ab..ac9c6f4d238 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -148,7 +148,6 @@ import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateS3Dao; import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.listener.VolumeStateListener; import com.cloud.storage.s3.S3Manager; @@ -235,8 +234,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected UserVmDao _userVmDao; @Inject - VolumeHostDao _volumeHostDao; - @Inject protected VMInstanceDao _vmInstanceDao; @Inject protected PrimaryDataStoreDao _storagePoolDao = null; @@ -1171,15 +1168,15 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @DB - List findAllVolumeIdInSnapshotTable(Long hostId) { - String sql = "SELECT volume_id from snapshots WHERE sechost_id=? GROUP BY volume_id"; + List findAllVolumeIdInSnapshotTable(Long storeId) { + String sql = "SELECT volume_id from snapshots, snapshot_store_ref WHERE store_id=? GROUP BY volume_id"; List list = new ArrayList(); try { Transaction txn = Transaction.currentTxn(); ResultSet rs = null; PreparedStatement pstmt = null; pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, hostId); + pstmt.setLong(1, storeId); rs = pstmt.executeQuery(); while (rs.next()) { list.add(rs.getLong(1)); @@ -1187,7 +1184,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return list; } catch (Exception e) { s_logger.debug("failed to get all volumes who has snapshots in secondary storage " - + hostId + " due to " + e.getMessage()); + + storeId + " due to " + e.getMessage()); return null; } @@ -1220,92 +1217,67 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C try { // Cleanup templates in secondary storage hosts List imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(null)); - for (DataStore store : imageStores) { + for (DataStore store : imageStores) { try { long storeId = store.getId(); List destroyedTemplateStoreVOs = this._templateStoreDao.listDestroyed(storeId); - s_logger.debug("Secondary storage garbage collector found " - + destroyedTemplateStoreVOs.size() - + " templates to cleanup on secondary storage host: " - + store.getName()); + s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size() + + " templates to cleanup on secondary storage host: " + store.getName()); for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) { - if (!_tmpltMgr - .templateIsDeleteable(destroyedTemplateStoreVO)) { + if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateStoreVO)) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Not deleting template at: " - + destroyedTemplateStoreVO); + s_logger.debug("Not deleting template at: " + destroyedTemplateStoreVO); } continue; } if (s_logger.isDebugEnabled()) { - s_logger.debug("Deleting template store: " - + destroyedTemplateStoreVO); + s_logger.debug("Deleting template store: " + destroyedTemplateStoreVO); } VMTemplateVO destroyedTemplate = this._vmTemplateDao.findById(destroyedTemplateStoreVO.getTemplateId()); - if ( destroyedTemplate == null ){ + if (destroyedTemplate == null) { s_logger.error("Cannot find template : " + destroyedTemplateStoreVO.getTemplateId() + " from template table"); - throw new CloudRuntimeException("Template " + destroyedTemplateStoreVO.getTemplateId() + " is found in secondary storage, but not found in template table"); + throw new CloudRuntimeException("Template " + destroyedTemplateStoreVO.getTemplateId() + + " is found in secondary storage, but not found in template table"); } - String installPath = destroyedTemplateStoreVO - .getInstallPath(); + String installPath = destroyedTemplateStoreVO.getInstallPath(); if (installPath != null) { EndPoint ep = _epSelector.select(store); - Command cmd = new DeleteTemplateCommand( - store.getTO(), - store.getUri(), - destroyedTemplateStoreVO - .getInstallPath(), - destroyedTemplate.getId(), - destroyedTemplate.getAccountId() - ); + Command cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), destroyedTemplateStoreVO.getInstallPath(), + destroyedTemplate.getId(), destroyedTemplate.getAccountId()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " - + destroyedTemplateStoreVO - + " due to " - + ((answer == null) ? "answer is null" - : answer.getDetails())); + s_logger.debug("Failed to delete " + destroyedTemplateStoreVO + " due to " + + ((answer == null) ? "answer is null" : answer.getDetails())); } else { - _templateStoreDao - .remove(destroyedTemplateStoreVO.getId()); - s_logger.debug("Deleted template at: " - + destroyedTemplateStoreVO - .getInstallPath()); + _templateStoreDao.remove(destroyedTemplateStoreVO.getId()); + s_logger.debug("Deleted template at: " + destroyedTemplateStoreVO.getInstallPath()); } } else { - _templateStoreDao.remove(destroyedTemplateStoreVO - .getId()); + _templateStoreDao.remove(destroyedTemplateStoreVO.getId()); } } } catch (Exception e) { - s_logger.warn( - "problem cleaning up templates in secondary storage store " - + store.getName(), e); + s_logger.warn("problem cleaning up templates in secondary storage store " + store.getName(), e); } } - List secondaryStorageHosts = _ssvmMgr - .listSecondaryStorageHostsInAllZones(); // Cleanup snapshot in secondary storage hosts - for (HostVO secondaryStorageHost : secondaryStorageHosts) { + for (DataStore store : imageStores) { try { - long hostId = secondaryStorageHost.getId(); - List vIDs = findAllVolumeIdInSnapshotTable(hostId); + List vIDs = findAllVolumeIdInSnapshotTable(store.getId()); if (vIDs == null) { continue; } for (Long volumeId : vIDs) { boolean lock = false; try { - VolumeVO volume = _volsDao - .findByIdIncludingRemoved(volumeId); + VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId); if (volume.getRemoved() == null) { - volume = _volsDao.acquireInLockTable(volumeId, - 10); + volume = _volsDao.acquireInLockTable(volumeId, 10); if (volume == null) { continue; } @@ -1315,25 +1287,18 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (snapshots == null) { continue; } - CleanupSnapshotBackupCommand cmd = new CleanupSnapshotBackupCommand( - secondaryStorageHost.getStorageUrl(), - secondaryStorageHost.getDataCenterId(), + EndPoint ep = _epSelector.select(store); + CleanupSnapshotBackupCommand cmd = new CleanupSnapshotBackupCommand(store.getUri(), store.getScope().getScopeId(), volume.getAccountId(), volumeId, snapshots); - Answer answer = _agentMgr.sendToSecStorage( - secondaryStorageHost, cmd); + Answer answer = ep.sendMessage(cmd); if ((answer == null) || !answer.getResult()) { - String details = "Failed to cleanup snapshots for volume " - + volumeId - + " due to " - + (answer == null ? "null" : answer - .getDetails()); + String details = "Failed to cleanup snapshots for volume " + volumeId + " due to " + + (answer == null ? "null" : answer.getDetails()); s_logger.warn(details); } } catch (Exception e1) { - s_logger.warn( - "problem cleaning up snapshots in secondary storage " - + secondaryStorageHost, e1); + s_logger.warn("problem cleaning up snapshots in secondary storage store " + store.getName(), e1); } finally { if (lock) { _volsDao.releaseFromLockTable(volumeId); @@ -1341,63 +1306,41 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } } catch (Exception e2) { - s_logger.warn( - "problem cleaning up snapshots in secondary storage " - + secondaryStorageHost, e2); + s_logger.warn("problem cleaning up snapshots in secondary storage store " + store.getName(), e2); } } // CleanUp volumes on Secondary Storage. - for (HostVO secondaryStorageHost : secondaryStorageHosts) { + for (DataStore store : imageStores) { try { - long hostId = secondaryStorageHost.getId(); - List destroyedVolumeHostVOs = _volumeHostDao - .listDestroyed(hostId); - s_logger.debug("Secondary storage garbage collector found " - + destroyedVolumeHostVOs.size() - + " templates to cleanup on secondary storage host: " - + secondaryStorageHost.getName()); - for (VolumeHostVO destroyedVolumeHostVO : destroyedVolumeHostVOs) { + List destroyedStoreVOs = _volumeStoreDao.listDestroyed(store.getId()); + s_logger.debug("Secondary storage garbage collector found " + destroyedStoreVOs.size() + + " volumes to cleanup on secondary storage host: " + store.getName()); + for (VolumeDataStoreVO destroyedStoreVO : destroyedStoreVOs) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Deleting volume host: " - + destroyedVolumeHostVO); + s_logger.debug("Deleting volume on store: " + destroyedStoreVO); } - String installPath = destroyedVolumeHostVO - .getInstallPath(); + String installPath = destroyedStoreVO.getInstallPath(); if (installPath != null) { - Answer answer = _agentMgr.sendToSecStorage( - secondaryStorageHost, - new DeleteVolumeCommand( - secondaryStorageHost - .getStorageUrl(), - destroyedVolumeHostVO - .getInstallPath())); - + EndPoint ep = _epSelector.select(store); + DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getUri(), destroyedStoreVO.getInstallPath()); + Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " - + destroyedVolumeHostVO - + " due to " - + ((answer == null) ? "answer is null" - : answer.getDetails())); + s_logger.debug("Failed to delete " + destroyedStoreVO + " due to " + + ((answer == null) ? "answer is null" : answer.getDetails())); } else { - _volumeHostDao.remove(destroyedVolumeHostVO - .getId()); - s_logger.debug("Deleted volume at: " - + destroyedVolumeHostVO - .getInstallPath()); + _volumeStoreDao.remove(destroyedStoreVO.getId()); + s_logger.debug("Deleted volume at: " + destroyedStoreVO.getInstallPath()); } } else { - _volumeHostDao - .remove(destroyedVolumeHostVO.getId()); + _volumeStoreDao.remove(destroyedStoreVO.getId()); } } } catch (Exception e2) { - s_logger.warn( - "problem cleaning up volumes in secondary storage " - + secondaryStorageHost, e2); + s_logger.warn("problem cleaning up volumes in secondary storage store " + store.getName(), e2); } } } catch (Exception e3) { diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index dcad55b2b45..57241b1757f 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -61,6 +61,8 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -123,12 +125,10 @@ import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolWorkDao; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateHostDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateS3Dao; import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; @@ -149,9 +149,6 @@ import com.cloud.utils.Pair; import com.cloud.utils.UriUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; @@ -233,7 +230,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @Inject protected UserVmDao _userVmDao; @Inject - VolumeHostDao _volumeHostDao; + VolumeDataStoreDao _volumeStoreDao; @Inject protected VMInstanceDao _vmInstanceDao; @Inject @@ -1248,9 +1245,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } if (volume.getState() == Volume.State.UploadOp) { - VolumeHostVO volumeHost = _volumeHostDao.findByVolumeId(volume + VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume .getId()); - if (volumeHost.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { throw new InvalidParameterValueException( "Please specify a volume that is not uploading"); } @@ -1424,8 +1421,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { private VolumeInfo copyVolume(StoragePoolVO rootDiskPool , VolumeInfo volume, VMInstanceVO vm, VMTemplateVO rootDiskTmplt, DataCenterVO dcVO, HostPodVO pod, DiskOfferingVO diskVO, ServiceOfferingVO svo, HypervisorType rootDiskHyperType) throws NoTransitionException { - VolumeHostVO volHostVO = _volumeHostDao.findByHostVolume(volume.getDataStore().getId(), volume.getId()); - if (!volHostVO + VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(volume.getDataStore().getId(), volume.getId()); + if (!volStoreVO .getFormat() .getFileExtension() .equals( @@ -1433,7 +1430,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { .getClusterId()))) { throw new InvalidParameterValueException( "Failed to attach volume to VM since volumes format " - + volHostVO.getFormat() + + volStoreVO.getFormat() .getFileExtension() + " is not compatible with the vm hypervisor type"); } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index b72c2021316..2afa4e668c9 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -96,8 +96,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject VolumeDao _volumeDao; @Inject - VolumeHostDao _volumeHostDao; - @Inject VolumeDataStoreDao _volumeStoreDao; @Inject AlertManager _alertMgr; @@ -310,7 +308,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId()); HypervisorType hyperType = tmplt.getHypervisorType(); - + if (hyperType != null && hyperType == HypervisorType.KVM) { //return "file://" + sourceServer.getParent() + "/" + srcTmpltStore.getInstallPath(); return "file://" + "/" + srcTmpltStore.getInstallPath(); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index f1b32ed271c..000430fca25 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -355,8 +355,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use @Inject protected ItWorkDao _workDao; @Inject - protected VolumeHostDao _volumeHostDao; - @Inject ResourceTagDao _resourceTagDao; @Inject PhysicalNetworkDao _physicalNetworkDao; From 8d29cdf804e0c4fe9fa1e9ed6d00bc2f6117b6e5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 11:54:42 -0700 Subject: [PATCH 058/303] Remove SnapshotVO.getSecHostId and SnapshotVO.setSecHostId references from codebase to use SnapshotDataStoreVO. --- core/src/com/cloud/storage/SnapshotVO.java | 11 --- .../motion/AncientDataMotionStrategy.java | 30 ++++---- .../storage/snapshot/SnapshotServiceImpl.java | 2 - .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../com/cloud/storage/dao/SnapshotDao.java | 2 - .../cloud/storage/dao/SnapshotDaoImpl.java | 74 +++++++------------ .../storage/snapshot/SnapshotManagerImpl.java | 27 ++++--- 7 files changed, 56 insertions(+), 92 deletions(-) diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index 78b96ec9779..dbfd7baa617 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -85,9 +85,6 @@ public class SnapshotVO implements Snapshot { @Column(name="s3_id") Long s3Id; - @Column(name="sechost_id") - Long secHostId; - @Column(name="prev_snap_id") long prevSnapshotId; @@ -190,14 +187,6 @@ public class SnapshotVO implements Snapshot { this.swiftId = swiftId; } - public Long getSecHostId() { - return secHostId; - } - - public void setSecHostId(Long secHostId) { - this.secHostId = secHostId; - } - @Override public HypervisorType getHypervisorType() { return hypervisorType; 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 index affe0308dba..84d2b16e91c 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -38,6 +38,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -113,6 +115,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @Inject SnapshotDao snapshotDao; @Inject + SnapshotDataStoreDao _snapshotStoreDao; + @Inject PrimaryDataStoreDao primaryDataStoreDao; @Inject DataStoreManager dataStoreMgr; @@ -622,12 +626,12 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return sendCommand(cmd, pool, template.getId(), zoneId, secStore); } - private HostVO getSecHost(long volumeId, long dcId) { + private DataStore getSecHost(long volumeId, long dcId) { Long id = snapshotDao.getSecHostId(volumeId); if ( id != null) { - return hostDao.findById(id); + return this.dataStoreMgr.getDataStore(id, DataStoreRole.Image); } - return this.templateMgr.getSecondaryStorageHost(dcId); + return this.dataStoreMgr.getImageStore(dcId); } protected Answer copySnapshot(DataObject srcObject, DataObject destObject) { @@ -636,9 +640,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { Long dcId = baseVolume.getDataCenterId(); Long accountId = baseVolume.getAccountId(); - HostVO secHost = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId()); - Long secHostId = secHost.getId(); - String secondaryStoragePoolUrl = secHost.getStorageUrl(); + DataStore secStore = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId()); + Long secHostId = secStore.getId(); + String secondaryStoragePoolUrl = secStore.getUri(); 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. @@ -681,16 +685,10 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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()); - } + snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName()); + // persist an entry in snapshot_store_ref + SnapshotDataStoreVO snapshotStore = new SnapshotDataStoreVO(secStore.getId(), snapshotVO.getId()); + this._snapshotStoreDao.persist(snapshotStore); if (answer.isFull()) { snapshotVO.setPrevSnapshotId(0L); } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 7eee7720330..633e193b939 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -191,9 +191,7 @@ public class SnapshotServiceImpl implements SnapshotService { snapshotVO.setPath(preSnapshotPath); snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); - snapshotVO.setSwiftId(preSnapshotVO.getSwiftId()); snapshotVO.setPrevSnapshotId(preSnapshotVO.getId()); - snapshotVO.setSecHostId(preSnapshotVO.getSecHostId()); snapshot.processEvent(Snapshot.Event.OperationNotPerformed); } else { long preSnapshotId = 0; diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index ac9c6f4d238..37fb3769156 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1169,7 +1169,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @DB List findAllVolumeIdInSnapshotTable(Long storeId) { - String sql = "SELECT volume_id from snapshots, snapshot_store_ref WHERE store_id=? GROUP BY volume_id"; + String sql = "SELECT volume_id from snapshots, snapshot_store_ref WHERE snapshots.id = snapshot_store_ref.snapshot_id and store_id=? GROUP BY volume_id"; List list = new ArrayList(); try { Transaction txn = Transaction.currentTxn(); diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java index 3ac9e77fb5d..e6aecc7654f 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDao.java +++ b/server/src/com/cloud/storage/dao/SnapshotDao.java @@ -37,8 +37,6 @@ public interface SnapshotDao extends GenericDao, StateDao listByVolumeIdVersion(long volumeId, String version); Long getSecHostId(long volumeId); long updateSnapshotSecHost(long dcId, long secHostId); - List listByHostId(Filter filter, long hostId); - List listByHostId(long hostId); public Long countSnapshotsForAccount(long accountId); List listByInstanceId(long instanceId, Snapshot.State... status); List listByStatus(long volumeId, Snapshot.State... status); diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index f55663fe204..2dd5da14265 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -54,9 +54,10 @@ import com.cloud.vm.dao.VMInstanceDao; @Local (value={SnapshotDao.class}) public class SnapshotDaoImpl extends GenericDaoBase implements SnapshotDao { public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName()); + //TODO: we should remove these direct sqls private static final String GET_LAST_SNAPSHOT = "SELECT id FROM snapshots where volume_id = ? AND id != ? AND path IS NOT NULL ORDER BY created DESC"; private static final String UPDATE_SNAPSHOT_VERSION = "UPDATE snapshots SET version = ? WHERE volume_id = ? AND version = ?"; - private static final String GET_SECHOST_ID = "SELECT sechost_id FROM snapshots where volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1"; + private static final String GET_SECHOST_ID = "SELECT store_id FROM snapshots, snapshot_store_ref where snapshots.id = snapshot_store_ref.snapshot_id AND volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1"; private static final String UPDATE_SECHOST_ID = "UPDATE snapshots SET sechost_id = ? WHERE data_center_id = ?"; private SearchBuilder VolumeIdSearch; @@ -64,7 +65,6 @@ public class SnapshotDaoImpl extends GenericDaoBase implements private SearchBuilder ParentIdSearch; private SearchBuilder backupUuidSearch; private SearchBuilder VolumeIdVersionSearch; - private SearchBuilder HostIdSearch; private SearchBuilder AccountIdSearch; private SearchBuilder InstanceIdSearch; private SearchBuilder StatusSearch; @@ -80,20 +80,20 @@ public class SnapshotDaoImpl extends GenericDaoBase implements sc.setParameters("prevSnapshotId", snapshotId); return findOneIncludingRemovedBy(sc); } - + @Override public List listByBackupUuid(long volumeId, String backupUuid) { SearchCriteria sc = backupUuidSearch.create(); sc.setParameters("backupUuid", backupUuid); return listBy(sc, null); } - + @Override public List listByVolumeIdType(long volumeId, Type type ) { return listByVolumeIdType(null, volumeId, type); } - - + + @Override public List listByVolumeIdVersion(long volumeId, String version ) { return listByVolumeIdVersion(null, volumeId, version); @@ -103,41 +103,28 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public List listByVolumeId(long volumeId) { return listByVolumeId(null, volumeId); } - + @Override public List listByVolumeId(Filter filter, long volumeId ) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); return listBy(sc, filter); } - - @Override - public List listByHostId(long hostId) { - return listByHostId(null, hostId); - } - - @Override - public List listByHostId(Filter filter, long hostId ) { - SearchCriteria sc = HostIdSearch.create(); - sc.setParameters("hostId", hostId); - sc.setParameters("status", Snapshot.State.BackedUp); - return listBy(sc, filter); - } - - @Override + + @Override public List listByVolumeIdIncludingRemoved(long volumeId) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); return listIncludingRemovedBy(sc, null); } - + public List listByVolumeIdType(Filter filter, long volumeId, Type type ) { SearchCriteria sc = VolumeIdTypeSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("type", type.ordinal()); return listBy(sc, filter); } - + public List listByVolumeIdVersion(Filter filter, long volumeId, String version ) { SearchCriteria sc = VolumeIdVersionSearch.create(); sc.setParameters("volumeId", volumeId); @@ -147,32 +134,27 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public SnapshotDaoImpl() { } - + @PostConstruct protected void init() { VolumeIdSearch = createSearchBuilder(); VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdSearch.done(); - - HostIdSearch = createSearchBuilder(); - HostIdSearch.and("hostId", HostIdSearch.entity().getSecHostId(), SearchCriteria.Op.EQ); - HostIdSearch.and("status", HostIdSearch.entity().getState(), SearchCriteria.Op.EQ); - HostIdSearch.done(); - + VolumeIdTypeSearch = createSearchBuilder(); VolumeIdTypeSearch.and("volumeId", VolumeIdTypeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdTypeSearch.and("type", VolumeIdTypeSearch.entity().getsnapshotType(), SearchCriteria.Op.EQ); VolumeIdTypeSearch.done(); - + VolumeIdVersionSearch = createSearchBuilder(); VolumeIdVersionSearch.and("volumeId", VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdVersionSearch.and("version", VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ); VolumeIdVersionSearch.done(); - + ParentIdSearch = createSearchBuilder(); ParentIdSearch.and("prevSnapshotId", ParentIdSearch.entity().getPrevSnapshotId(), SearchCriteria.Op.EQ); ParentIdSearch.done(); - + backupUuidSearch = createSearchBuilder(); backupUuidSearch.and("backupUuid", backupUuidSearch.entity().getBackupSnapshotId(), SearchCriteria.Op.EQ); backupUuidSearch.done(); @@ -180,18 +162,18 @@ public class SnapshotDaoImpl extends GenericDaoBase implements AccountIdSearch = createSearchBuilder(); AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.done(); - + StatusSearch = createSearchBuilder(); StatusSearch.and("volumeId", StatusSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); StatusSearch.and("status", StatusSearch.entity().getState(), SearchCriteria.Op.IN); StatusSearch.done(); - + CountSnapshotsByAccount = createSearchBuilder(Long.class); - CountSnapshotsByAccount.select(null, Func.COUNT, null); + CountSnapshotsByAccount.select(null, Func.COUNT, null); CountSnapshotsByAccount.and("account", CountSnapshotsByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); CountSnapshotsByAccount.and("removed", CountSnapshotsByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); CountSnapshotsByAccount.done(); - + InstanceIdSearch = createSearchBuilder(); InstanceIdSearch.and("status", InstanceIdSearch.entity().getState(), SearchCriteria.Op.IN); @@ -227,7 +209,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } } catch (Exception ex) { } - return null; + return null; } @Override public long getLastSnapshot(long volumeId, long snapId) { @@ -265,7 +247,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } return 0; } - + @Override public long updateSnapshotSecHost(long dcId, long secHostId) { Transaction txn = Transaction.currentTxn(); @@ -289,20 +271,20 @@ public class SnapshotDaoImpl extends GenericDaoBase implements sc.setParameters("account", accountId); return customSearch(sc, null).get(0); } - + @Override public List listByInstanceId(long instanceId, Snapshot.State... status) { SearchCriteria sc = this.InstanceIdSearch.create(); - + if (status != null && status.length != 0) { sc.setParameters("status", (Object[])status); } - + sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready); sc.setJoinParameters("instanceVolumes", "instanceId", instanceId); return listBy(sc, null); } - + @Override public List listByStatus(long volumeId, Snapshot.State... status) { SearchCriteria sc = this.StatusSearch.create(); @@ -310,7 +292,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements sc.setParameters("status", (Object[])status); return listBy(sc, null); } - + @Override @DB public boolean remove(Long id) { @@ -324,7 +306,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements txn.commit(); return result; } - + @Override public List listAllByStatus(Snapshot.State... status) { SearchCriteria sc = this.StatusSearch.create(); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 88bcc6ac19d..a7842fadbbf 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.api.command.user.snapshot.CreateSnapshotPolicyCmd; import org.apache.cloudstack.api.command.user.snapshot.DeleteSnapshotPoliciesCmd; import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd; import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd; +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.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -38,6 +39,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -79,6 +82,7 @@ import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Type; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.SnapshotScheduleVO; import com.cloud.storage.SnapshotVO; @@ -146,6 +150,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Inject protected SnapshotDao _snapshotDao; @Inject + protected SnapshotDataStoreDao _snapshotStoreDao; + @Inject protected PrimaryDataStoreDao _storagePoolDao; @Inject protected EventDao _eventDao; @@ -523,24 +529,17 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } } - private HostVO getSecondaryStorageHost(SnapshotVO snapshot) { - HostVO secHost = null; - if( snapshot.getSwiftId() == null || snapshot.getSwiftId() == 0) { - secHost = _hostDao.findById(snapshot.getSecHostId()); - } else { - Long dcId = snapshot.getDataCenterId(); - secHost = this.templateMgr.getSecondaryStorageHost(dcId); - } - return secHost; - } @Override public String getSecondaryStorageURL(SnapshotVO snapshot) { - HostVO secHost = getSecondaryStorageHost(snapshot); - if (secHost != null) { - return secHost.getStorageUrl(); + SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId()); + if (snapshotStore != null){ + DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); + if ( store != null ){ + return store.getUri(); + } } - throw new CloudRuntimeException("Can not find secondary storage"); + throw new CloudRuntimeException("Can not find secondary storage hosting the snapshot"); } @Override From f16f92dd1d21c62ea8cfa8f1215ef44808493fd9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 15:06:36 -0700 Subject: [PATCH 059/303] Remove TemplateManager.getSecondaryStorageHost api. --- .../cloud/server/ManagementServerImpl.java | 9 +-- .../storage/snapshot/SnapshotManagerImpl.java | 9 ++- .../cloud/storage/upload/UploadListener.java | 17 +++-- .../cloud/storage/upload/UploadMonitor.java | 3 +- .../storage/upload/UploadMonitorImpl.java | 72 +++++++++---------- .../com/cloud/template/TemplateManager.java | 4 -- .../cloud/template/TemplateManagerImpl.java | 29 -------- 7 files changed, 58 insertions(+), 85 deletions(-) diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c2871d9f4d8..92d8c7bc606 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -313,6 +313,7 @@ import org.apache.cloudstack.api.command.user.vpc.*; import org.apache.cloudstack.api.command.user.vpn.*; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.api.response.ExtractResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -2673,8 +2674,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe long accountId = volume.getAccountId(); StoragePool srcPool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); - HostVO sserver = this.templateMgr.getSecondaryStorageHost(zoneId); - String secondaryStorageURL = sserver.getStorageUrl(); + DataStore secStore = this.dataStoreMgr.getImageStore(zoneId); + String secondaryStorageURL = secStore.getUri(); List extractURLList = _uploadDao.listByTypeUploadStatus(volumeId, Upload.Type.VOLUME, UploadVO.Status.DOWNLOAD_URL_CREATED); @@ -2682,7 +2683,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return extractURLList.get(0).getId(); // If download url already // exists then return } else { - UploadVO uploadJob = _uploadMonitor.createNewUploadEntry(sserver.getId(), volumeId, UploadVO.Status.COPY_IN_PROGRESS, Upload.Type.VOLUME, + UploadVO uploadJob = _uploadMonitor.createNewUploadEntry(secStore.getId(), volumeId, UploadVO.Status.COPY_IN_PROGRESS, Upload.Type.VOLUME, url, extractMode); s_logger.debug("Extract Mode - " + uploadJob.getMode()); uploadJob = _uploadDao.createForUpdate(uploadJob.getId()); @@ -2740,7 +2741,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe if (extractMode == Mode.FTP_UPLOAD) { // Now that the volume is // copied perform the actual // uploading - _uploadMonitor.extractVolume(uploadJob, sserver, volume, url, zoneId, volumeLocalPath, cmd.getStartEventId(), job.getId(), _asyncMgr); + _uploadMonitor.extractVolume(uploadJob, secStore, volume, url, zoneId, volumeLocalPath, cmd.getStartEventId(), job.getId(), _asyncMgr); return uploadJob.getId(); } else { // Volume is copied now make it visible under apache and // create a URL. diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index a7842fadbbf..624d1d5af95 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -358,8 +358,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, VolumeVO volume = _volsDao.findById(volumeId); Long dcId = volume.getDataCenterId(); Long accountId = volume.getAccountId(); - HostVO secHost = this.templateMgr.getSecondaryStorageHost(dcId); - String secondaryStoragePoolUrl = secHost.getStorageUrl(); + DataStore secStore = this.dataStoreMgr.getImageStore(dcId); Long swiftId = ss.getSwiftId(); SwiftTO swift = _swiftMgr.getSwiftTO(swiftId); @@ -376,7 +375,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String parent = null; try { for (String backupUuid : BackupUuids) { - downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swift, secondaryStoragePoolUrl, dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait); + downloadSnapshotFromSwiftCommand cmd = new downloadSnapshotFromSwiftCommand(swift, secStore.getUri(), dcId, accountId, volumeId, parent, backupUuid, _backupsnapshotwait); Answer answer = _agentMgr.sendToSSVM(dcId, cmd); if ((answer == null) || !answer.getResult()) { throw new CloudRuntimeException("downloadSnapshotsFromSwift failed "); @@ -409,7 +408,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, final VolumeVO volume = _volsDao.findById(snapshot.getVolumeId()); final Long zoneId = volume.getDataCenterId(); - final HostVO secHost = this.templateMgr.getSecondaryStorageHost(zoneId); + final DataStore secStore = this.dataStoreMgr.getImageStore(zoneId); final S3TO s3 = _s3Mgr.getS3TO(snapshot.getS3Id()); final List backupUuids = determineBackupUuids(snapshot); @@ -418,7 +417,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, String parent = null; for (final String backupUuid : backupUuids) { final DownloadSnapshotFromS3Command cmd = new DownloadSnapshotFromS3Command( - s3, parent, secHost.getStorageUrl(), zoneId, + s3, parent, secStore.getUri(), zoneId, volume.getAccountId(), volume.getId(), backupUuid, _backupsnapshotwait); final Answer answer = _agentMgr.sendToSSVM(zoneId, cmd); diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index 891610f46f6..8d9cbb64102 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -24,6 +24,8 @@ import java.util.Map; import java.util.Timer; import java.util.TimerTask; +import javax.inject.Inject; + import org.apache.cloudstack.api.command.user.iso.ExtractIsoCmd; import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; import org.apache.log4j.Level; @@ -42,6 +44,9 @@ import com.cloud.agent.api.storage.UploadProgressCommand; import com.cloud.agent.api.storage.UploadProgressCommand.RequestType; import org.apache.cloudstack.api.command.user.template.ExtractTemplateCmd; import org.apache.cloudstack.api.response.ExtractResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobManager; @@ -109,7 +114,7 @@ public class UploadListener implements Listener { } - private HostVO sserver; + private DataStore sserver; private boolean uploadActive = true; @@ -134,6 +139,7 @@ public class UploadListener implements Listener { private long eventId; private AsyncJobManager asyncMgr; private ExtractResponse resultObj; + @Inject EndPointSelector _epSelector; public AsyncJobManager getAsyncMgr() { return asyncMgr; @@ -162,7 +168,7 @@ public class UploadListener implements Listener { private final Map stateMap = new HashMap(); private Long uploadId; - public UploadListener(HostVO host, Timer _timer, UploadDao uploadDao, + public UploadListener(DataStore host, Timer _timer, UploadDao uploadDao, UploadVO uploadObj, UploadMonitorImpl uploadMonitor, UploadCommand cmd, Long accountId, String typeName, Type type, long eventId, long asyncJobId, AsyncJobManager asyncMgr) { this.sserver = host; @@ -272,7 +278,7 @@ public class UploadListener implements Listener { public void setUploadInactive(Status reason) { uploadActive=false; - uploadMonitor.handleUploadEvent(sserver, accountId, typeName, type, uploadId, reason, eventId); + uploadMonitor.handleUploadEvent(accountId, typeName, type, uploadId, reason, eventId); } public void logUploadStart() { @@ -430,8 +436,9 @@ public class UploadListener implements Listener { log("Sending progress command ", Level.TRACE); } try { - uploadMonitor.send(sserver.getId(), new UploadProgressCommand(getCommand(), getJobId(), reqType), this); - } catch (AgentUnavailableException e) { + EndPoint ep = _epSelector.select(sserver); + ep.sendMessageAsyncWithListener(new UploadProgressCommand(getCommand(), getJobId(), reqType), this); + } catch (Exception e) { s_logger.debug("Send command failed", e); setDisconnected(); } diff --git a/server/src/com/cloud/storage/upload/UploadMonitor.java b/server/src/com/cloud/storage/upload/UploadMonitor.java index dd50d1ae40f..4e410480312 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitor.java +++ b/server/src/com/cloud/storage/upload/UploadMonitor.java @@ -17,6 +17,7 @@ package com.cloud.storage.upload; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import com.cloud.async.AsyncJobManager; @@ -48,7 +49,7 @@ public interface UploadMonitor extends Manager{ UploadVO createNewUploadEntry(Long hostId, Long typeId, Status uploadState, Type type, String errorString, Mode extractMode); - void extractVolume(UploadVO uploadVolumeObj, HostVO sserver, VolumeVO volume, String url, + void extractVolume(UploadVO uploadVolumeObj, DataStore secStore, VolumeVO volume, String url, Long dataCenterId, String installPath, long eventId, long asyncJobId, AsyncJobManager asyncMgr); diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 3f07cba1b75..0d0883e4859 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -156,20 +156,21 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } @Override - public void extractVolume(UploadVO uploadVolumeObj, HostVO sserver, VolumeVO volume, String url, Long dataCenterId, String installPath, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ + public void extractVolume(UploadVO uploadVolumeObj, DataStore secStore, VolumeVO volume, String url, Long dataCenterId, String installPath, long eventId, long asyncJobId, AsyncJobManager asyncMgr){ uploadVolumeObj.setUploadState(Upload.Status.NOT_UPLOADED); _uploadDao.update(uploadVolumeObj.getId(), uploadVolumeObj); start(); UploadCommand ucmd = new UploadCommand(url, volume.getId(), volume.getSize(), installPath, Type.VOLUME); - UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadVolumeObj, this, ucmd, volume.getAccountId(), volume.getName(), Type.VOLUME, eventId, asyncJobId, asyncMgr); + UploadListener ul = new UploadListener(secStore, _timer, _uploadDao, uploadVolumeObj, this, ucmd, volume.getAccountId(), volume.getName(), Type.VOLUME, eventId, asyncJobId, asyncMgr); _listenerMap.put(uploadVolumeObj, ul); try { - send(sserver.getId(), ucmd, ul); - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start upload of volume " + volume.getName() + " from " + sserver.getName() + " to " +url, e); + EndPoint ep = _epSelector.select(secStore); + ep.sendMessageAsyncWithListener(ucmd, ul); + } catch (Exception e) { + s_logger.warn("Unable to start upload of volume " + volume.getName() + " from " + secStore.getName() + " to " +url, e); ul.setDisconnected(); ul.scheduleStatusCheck(RequestType.GET_OR_RESTART); } @@ -181,23 +182,22 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { Type type = (template.getFormat() == ImageFormat.ISO) ? Type.ISO : Type.TEMPLATE ; - List storageServers = _resourceMgr.listAllHostsInOneZoneByType(Host.Type.SecondaryStorage, dataCenterId); - HostVO sserver = storageServers.get(0); + DataStore secStore = this.storeMgr.getImageStore(dataCenterId); - UploadVO uploadTemplateObj = new UploadVO(sserver.getId(), template.getId(), new Date(), + UploadVO uploadTemplateObj = new UploadVO(secStore.getId(), template.getId(), new Date(), Upload.Status.NOT_UPLOADED, type, url, Mode.FTP_UPLOAD); _uploadDao.persist(uploadTemplateObj); if(vmTemplateHost != null) { start(); UploadCommand ucmd = new UploadCommand(template, url, vmTemplateHost.getInstallPath(), vmTemplateHost.getSize()); - UploadListener ul = new UploadListener(sserver, _timer, _uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), template.getName(), type, eventId, asyncJobId, asyncMgr); + UploadListener ul = new UploadListener(secStore, _timer, _uploadDao, uploadTemplateObj, this, ucmd, template.getAccountId(), template.getName(), type, eventId, asyncJobId, asyncMgr); _listenerMap.put(uploadTemplateObj, ul); - - try { - send(sserver.getId(), ucmd, ul); - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start upload of " + template.getUniqueName() + " from " + sserver.getName() + " to " +url, e); + try{ + EndPoint ep = _epSelector.select(secStore); + ep.sendMessageAsyncWithListener(ucmd, ul); + } catch (Exception e) { + s_logger.warn("Unable to start upload of " + template.getUniqueName() + " from " + secStore.getName() + " to " +url, e); ul.setDisconnected(); ul.scheduleStatusCheck(RequestType.GET_OR_RESTART); } @@ -282,19 +282,18 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { // Create Symlink at ssvm String uuid = UUID.randomUUID().toString() + path.substring(path.length() - 4) ; // last 4 characters of the path specify the format like .vhd - HostVO secStorage = ApiDBUtils.findHostById(ApiDBUtils.findUploadById(uploadId).getHostId()); - HostVO ssvm = _ssvmMgr.pickSsvmHost(secStorage); - if( ssvm == null ) { - errorString = "There is no secondary storage VM for secondary storage host " + secStorage.getName(); + DataStore secStore = this.storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getHostId(), DataStoreRole.Image); + EndPoint ep = _epSelector.select(secStore); + if( ep == null ) { + errorString = "There is no secondary storage VM for secondary storage host " + secStore.getName(); throw new CloudRuntimeException(errorString); } - CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(secStorage.getParent(), path, uuid); - try { - send(ssvm.getId(), cmd, null); - } catch (AgentUnavailableException e) { - errorString = "Unable to create a link for " +type+ " id:"+entityId + "," + e.getMessage(); - s_logger.warn(errorString, e); + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreVO)secStore).getParent(), path, uuid); + Answer ans = ep.sendMessage(cmd); + if (ans == null || !ans.getResult()) { + errorString = "Unable to create a link for " +type+ " id:"+entityId + "," + ans.getDetails(); + s_logger.warn(errorString); throw new CloudRuntimeException(errorString); } @@ -342,9 +341,6 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { - public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException { - _agentMgr.send(hostId, new Commands(cmd), listener); - } @Override public boolean configure(String name, Map params) @@ -382,7 +378,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { return true; } - public void handleUploadEvent(HostVO host, Long accountId, String typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason, long eventId) { + public void handleUploadEvent(Long accountId, String typeName, Type type, Long uploadId, com.cloud.storage.Upload.Status reason, long eventId) { if ((reason == Upload.Status.UPLOADED) || (reason==Upload.Status.ABANDONED)){ UploadVO uploadObj = new UploadVO(uploadId); @@ -463,23 +459,25 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { for (UploadVO extractJob : extractJobs){ if( getTimeDiff(extractJob.getLastUpdated()) > EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){ String path = extractJob.getInstallPath(); - HostVO secStorage = ApiDBUtils.findHostById(extractJob.getHostId()); + DataStore secStore = this.storeMgr.getDataStore(extractJob.getHostId(), DataStoreRole.Image); + // Would delete the symlink for the Type and if Type == VOLUME then also the volume - DeleteEntityDownloadURLCommand cmd = new DeleteEntityDownloadURLCommand(path, extractJob.getType(),extractJob.getUploadUrl(), secStorage.getParent()); - HostVO ssvm = _ssvmMgr.pickSsvmHost(secStorage); - if( ssvm == null ) { + DeleteEntityDownloadURLCommand cmd = new DeleteEntityDownloadURLCommand(path, extractJob.getType(),extractJob.getUploadUrl(), ((ImageStoreVO)secStore).getParent()); + EndPoint ep = _epSelector.select(secStore); + if( ep == null ) { s_logger.warn("UploadMonitor cleanup: There is no secondary storage VM for secondary storage host " + extractJob.getHostId()); continue; //TODO: why continue? why not break? } if (s_logger.isDebugEnabled()) { - s_logger.debug("UploadMonitor cleanup: Sending deletion of extract URL "+ extractJob.getUploadUrl() + " to ssvm " + ssvm.getId()); + s_logger.debug("UploadMonitor cleanup: Sending deletion of extract URL "+ extractJob.getUploadUrl() + " to ssvm " + ep.getHostAddr()); } - try { - send(ssvm.getId(), cmd, null); //TODO: how do you know if it was successful? + Answer ans = ep.sendMessage(cmd); + if ( ans != null && ans.getResult()){ _uploadDao.remove(extractJob.getId()); - } catch (AgentUnavailableException e) { - s_logger.warn("UploadMonitor cleanup: Unable to delete the link for " + extractJob.getType()+ " id=" + extractJob.getTypeId()+ " url="+ extractJob.getUploadUrl() + " on ssvm " + ssvm.getId(), e); + } + else{ + s_logger.warn("UploadMonitor cleanup: Unable to delete the link for " + extractJob.getType()+ " id=" + extractJob.getTypeId()+ " url="+ extractJob.getUploadUrl() + " on ssvm " + ep.getHostAddr()); } } } diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index dedb0b480d6..202feefcb3e 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -100,10 +100,6 @@ public interface TemplateManager extends TemplateApiService{ DataStore getImageStore(long zoneId, long tmpltId); - HostVO getSecondaryStorageHost(long zoneId); - - List getSecondaryStorageHosts(long zoneId); - Long getTemplateSize(long templateId, long zoneId); DataStore getImageStore(String storeUuid, Long zoneId); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index abe467a98af..eb628a9fab5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1742,35 +1742,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } - @Override - public HostVO getSecondaryStorageHost(long zoneId) { - List hosts = _ssvmMgr - .listSecondaryStorageHostsInOneZone(zoneId); - if (hosts == null || hosts.size() == 0) { - hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId); - if (hosts.isEmpty()) { - return null; - } - } - - int size = hosts.size(); - Random rn = new Random(); - int index = rn.nextInt(size); - return hosts.get(index); - } - - @Override - public List getSecondaryStorageHosts(long zoneId) { - List hosts = _ssvmMgr - .listSecondaryStorageHostsInOneZone(zoneId); - if (hosts == null || hosts.size() == 0) { - hosts = _ssvmMgr.listLocalSecondaryStorageHostsInOneZone(zoneId); - if (hosts.isEmpty()) { - return new ArrayList(); - } - } - return hosts; - } @Override public Long getTemplateSize(long templateId, long zoneId) { From 0a976d5fd508aa62e24e634c17c750bf48a3f85d Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 15:20:09 -0700 Subject: [PATCH 060/303] Change Upload table to store dataStoreId instead of hostId. --- api/src/com/cloud/storage/Upload.java | 2 +- core/src/com/cloud/storage/UploadVO.java | 22 +++++++++---------- .../com/cloud/storage/dao/UploadDaoImpl.java | 2 +- .../storage/upload/UploadMonitorImpl.java | 6 ++--- setup/db/db/schema-410to420.sql | 10 ++++++--- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/api/src/com/cloud/storage/Upload.java b/api/src/com/cloud/storage/Upload.java index ac3836caf55..69e10418a27 100755 --- a/api/src/com/cloud/storage/Upload.java +++ b/api/src/com/cloud/storage/Upload.java @@ -35,7 +35,7 @@ public interface Upload extends InternalIdentity, Identity { FTP_UPLOAD, HTTP_DOWNLOAD } - long getHostId(); + long getDataStoreId(); Date getCreated(); diff --git a/core/src/com/cloud/storage/UploadVO.java b/core/src/com/cloud/storage/UploadVO.java index d761bf17e3b..fe8b81280fd 100755 --- a/core/src/com/cloud/storage/UploadVO.java +++ b/core/src/com/cloud/storage/UploadVO.java @@ -32,7 +32,6 @@ import javax.persistence.TemporalType; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GenericDaoBase; -import org.apache.cloudstack.api.InternalIdentity; @Entity @Table(name="upload") @@ -45,7 +44,7 @@ public class UploadVO implements Upload { private String uuid; @Column(name="host_id") - private long hostId; + private long storeId; @Column(name="type_id") private long typeId; @@ -85,12 +84,12 @@ public class UploadVO implements Upload { private String installPath; @Override - public long getHostId() { - return hostId; + public long getDataStoreId() { + return storeId; } - public void setHostId(long hostId) { - this.hostId = hostId; + public void setDataStoreId(long hostId) { + this.storeId = hostId; } @Override @@ -99,7 +98,8 @@ public class UploadVO implements Upload { } - public String getUuid() { + @Override + public String getUuid() { return uuid; } @@ -119,7 +119,7 @@ public class UploadVO implements Upload { public UploadVO(long hostId, long templateId) { super(); - this.hostId = hostId; + this.storeId = hostId; this.typeId = templateId; this.uuid = UUID.randomUUID().toString(); } @@ -128,7 +128,7 @@ public class UploadVO implements Upload { Status uploadState, Type type, String uploadUrl, Mode mode) { super(); - this.hostId = hostId; + this.storeId = hostId; this.typeId = typeId; this.lastUpdated = lastUpdated; this.uploadState = uploadState; @@ -142,7 +142,7 @@ public class UploadVO implements Upload { Status uploadState, int uploadPercent, Type type, Mode mode) { super(); - this.hostId = hostId; + this.storeId = hostId; this.typeId = typeId; this.lastUpdated = lastUpdated; this.uploadState = uploadState; @@ -182,7 +182,7 @@ public class UploadVO implements Upload { public boolean equals(Object obj) { if (obj instanceof UploadVO) { UploadVO other = (UploadVO)obj; - return (this.typeId==other.getTypeId() && this.hostId==other.getHostId() && this.type == other.getType()); + return (this.typeId==other.getTypeId() && this.storeId==other.getDataStoreId() && this.type == other.getType()); } return false; } diff --git a/server/src/com/cloud/storage/dao/UploadDaoImpl.java b/server/src/com/cloud/storage/dao/UploadDaoImpl.java index 31fad43e257..4c6da393eb3 100755 --- a/server/src/com/cloud/storage/dao/UploadDaoImpl.java +++ b/server/src/com/cloud/storage/dao/UploadDaoImpl.java @@ -54,7 +54,7 @@ public class UploadDaoImpl extends GenericDaoBase implements Upl typeUploadStatusSearch.done(); typeHostAndUploadStatusSearch = createSearchBuilder(); - typeHostAndUploadStatusSearch.and("host_id", typeHostAndUploadStatusSearch.entity().getHostId(), SearchCriteria.Op.EQ); + typeHostAndUploadStatusSearch.and("host_id", typeHostAndUploadStatusSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); typeHostAndUploadStatusSearch.and("upload_state", typeHostAndUploadStatusSearch.entity().getUploadState(), SearchCriteria.Op.EQ); typeHostAndUploadStatusSearch.done(); diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 0d0883e4859..9eac22730ce 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -282,7 +282,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { // Create Symlink at ssvm String uuid = UUID.randomUUID().toString() + path.substring(path.length() - 4) ; // last 4 characters of the path specify the format like .vhd - DataStore secStore = this.storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getHostId(), DataStoreRole.Image); + DataStore secStore = this.storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(secStore); if( ep == null ) { errorString = "There is no secondary storage VM for secondary storage host " + secStore.getName(); @@ -459,14 +459,14 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { for (UploadVO extractJob : extractJobs){ if( getTimeDiff(extractJob.getLastUpdated()) > EXTRACT_URL_LIFE_LIMIT_IN_SECONDS ){ String path = extractJob.getInstallPath(); - DataStore secStore = this.storeMgr.getDataStore(extractJob.getHostId(), DataStoreRole.Image); + DataStore secStore = this.storeMgr.getDataStore(extractJob.getDataStoreId(), DataStoreRole.Image); // Would delete the symlink for the Type and if Type == VOLUME then also the volume DeleteEntityDownloadURLCommand cmd = new DeleteEntityDownloadURLCommand(path, extractJob.getType(),extractJob.getUploadUrl(), ((ImageStoreVO)secStore).getParent()); EndPoint ep = _epSelector.select(secStore); if( ep == null ) { - s_logger.warn("UploadMonitor cleanup: There is no secondary storage VM for secondary storage host " + extractJob.getHostId()); + s_logger.warn("UploadMonitor cleanup: There is no secondary storage VM for secondary storage host " + extractJob.getDataStoreId()); continue; //TODO: why continue? why not break? } if (s_logger.isDebugEnabled()) { diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 9519266e7f5..7e3704dfd96 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -136,7 +136,7 @@ CREATE TABLE `cloud`.`template_store_ref` ( `destroyed` tinyint(1) COMMENT 'indicates whether the template_store entry was destroyed by the user or not', `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', PRIMARY KEY (`id`), --- CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, +-- CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_template_store_ref__store_id`(`store_id`), CONSTRAINT `fk_template_store_ref__template_id` FOREIGN KEY `fk_template_store_ref__template_id` (`template_id`) REFERENCES `vm_template` (`id`), INDEX `i_template_store_ref__template_id`(`template_id`) @@ -149,6 +149,10 @@ CREATE TABLE `cloud`.`template_store_ref` ( -- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `s3_id`; -- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `sechost_id`; +-- change upload host_id FK to point to image_store table +ALTER TABLE `cloud`.`upload` DROP FOREIGN KEY `fk_upload__host_id`; +ALTER TABLE `cloud`.`upload` ADD CONSTRAINT `fk_upload__store_id` FOREIGN KEY(`host_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE; + CREATE TABLE `cloud`.`snapshot_store_ref` ( `id` bigint unsigned NOT NULL auto_increment, `store_id` bigint unsigned NOT NULL, @@ -162,7 +166,7 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `state` varchar(255) NOT NULL, `destroyed` tinyint(1) COMMENT 'indicates whether the snapshot_store entry was destroyed by the user or not', PRIMARY KEY (`id`), - CONSTRAINT `fk_snapshot_store_ref__store_id` FOREIGN KEY `fk_snapshot_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_snapshot_store_ref__store_id` FOREIGN KEY `fk_snapshot_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_snapshot_store_ref__store_id`(`store_id`), CONSTRAINT `fk_snapshot_store_ref__snapshot_id` FOREIGN KEY `fk_snapshot_store_ref__snapshot_id` (`snapshot_id`) REFERENCES `snapshots` (`id`), INDEX `i_snapshot_store_ref__snapshot_id`(`snapshot_id`) @@ -189,7 +193,7 @@ CREATE TABLE `cloud`.`volume_store_ref` ( `format` varchar(32) NOT NULL COMMENT 'format for the volume', `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', PRIMARY KEY (`id`), - CONSTRAINT `fk_volume_store_ref__store_id` FOREIGN KEY `fk_volume_store_ref__store_id` (`store_id`) REFERENCES `image_data_store` (`id`) ON DELETE CASCADE, + CONSTRAINT `fk_volume_store_ref__store_id` FOREIGN KEY `fk_volume_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_volume_store_ref__store_id`(`store_id`), CONSTRAINT `fk_volume_store_ref__volume_id` FOREIGN KEY `fk_volume_store_ref__volume_id` (`volume_id`) REFERENCES `volumes` (`id`), INDEX `i_volume_store_ref__volume_id`(`volume_id`) From 5b76e4914c760d046224d21fa9876b147c9f6e62 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 16:21:41 -0700 Subject: [PATCH 061/303] Remove sendToSecStorage methods from agentManager to use EndPoint instead. --- .../test/DirectAgentManagerSimpleImpl.java | 12 --------- server/src/com/cloud/agent/AgentManager.java | 4 --- .../cloud/agent/manager/AgentManagerImpl.java | 26 ------------------- .../com/cloud/agent/MockAgentManagerImpl.java | 10 ------- 4 files changed, 52 deletions(-) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index 220a7b01f6f..6941ff8cfdc 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -175,18 +175,6 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } - @Override - public void sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) throws AgentUnavailableException { - // TODO Auto-generated method stub - - } - - @Override - public Answer sendToSecStorage(HostVO ssHost, Command cmd) { - // TODO Auto-generated method stub - return null; - } - @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { diff --git a/server/src/com/cloud/agent/AgentManager.java b/server/src/com/cloud/agent/AgentManager.java index e4d55979191..02dd10d810f 100755 --- a/server/src/com/cloud/agent/AgentManager.java +++ b/server/src/com/cloud/agent/AgentManager.java @@ -137,10 +137,6 @@ public interface AgentManager extends Manager { Answer sendTo(Long dcId, HypervisorType type, Command cmd); - void sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) throws AgentUnavailableException; - - Answer sendToSecStorage(HostVO ssHost, Command cmd); - /* working as a lock while agent is being loaded */ public boolean tapLoadingAgents(Long hostId, TapAgentsAction action); diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java b/server/src/com/cloud/agent/manager/AgentManagerImpl.java index a32e0103d75..fb857a707c8 100755 --- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java +++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java @@ -377,32 +377,6 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl } - @Override - public Answer sendToSecStorage(HostVO ssHost, Command cmd) { - if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) { - return easySend(ssHost.getId(), cmd); - } else if ( ssHost.getType() == Host.Type.SecondaryStorage) { - return sendToSSVM(ssHost.getDataCenterId(), cmd); - } else { - String msg = "do not support Secondary Storage type " + ssHost.getType(); - s_logger.warn(msg); - return new Answer(cmd, false, msg); - } - } - - @Override - public void sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) throws AgentUnavailableException { - if( ssHost.getType() == Host.Type.LocalSecondaryStorage ) { - send(ssHost.getId(), new Commands(cmd), listener); - } else if ( ssHost.getType() == Host.Type.SecondaryStorage) { - sendToSSVM(ssHost.getDataCenterId(), cmd, listener); - } else { - String err = "do not support Secondary Storage type " + ssHost.getType(); - s_logger.warn(err); - throw new CloudRuntimeException(err); - } - } - private void sendToSSVM(final long dcId, final Command cmd, final Listener listener) throws AgentUnavailableException { List ssAHosts = _ssvmMgr.listUpAndConnectingSecondaryStorageVmHost(dcId); diff --git a/server/test/com/cloud/agent/MockAgentManagerImpl.java b/server/test/com/cloud/agent/MockAgentManagerImpl.java index 3ebb5495114..01f4e9cb071 100755 --- a/server/test/com/cloud/agent/MockAgentManagerImpl.java +++ b/server/test/com/cloud/agent/MockAgentManagerImpl.java @@ -131,16 +131,6 @@ public class MockAgentManagerImpl extends ManagerBase implements AgentManager { return null; } - @Override - public void sendToSecStorage(HostVO ssHost, Command cmd, Listener listener) { - } - - @Override - public Answer sendToSecStorage(HostVO ssHost, Command cmd) { - // TODO Auto-generated method stub - return null; - } - @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { From 4c174a6867f353654ec2d7178b76bfc0c66c232a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 17:30:38 -0700 Subject: [PATCH 062/303] Fix DeleteSnapshotBackupCommand to pass dataStore information. --- .../api/DeleteSnapshotBackupCommand.java | 22 ++--- .../resource/NfsSecondaryStorageResource.java | 90 +++++++++---------- .../storage/snapshot/SnapshotObject.java | 24 ++--- .../storage/snapshot/SnapshotServiceImpl.java | 13 ++- .../CloudStackImageStoreDriverImpl.java | 28 +++--- .../driver/S3ImageStoreDriverImpl.java | 75 ++++++++-------- .../driver/SwiftImageStoreDriverImpl.java | 74 +++++++-------- .../storage/snapshot/SnapshotManagerImpl.java | 47 +++------- 8 files changed, 175 insertions(+), 198 deletions(-) diff --git a/api/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java b/api/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java index 6114148954f..89145d31838 100644 --- a/api/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java +++ b/api/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java @@ -17,6 +17,7 @@ package com.cloud.agent.api; import com.cloud.agent.api.LogLevel.Log4jLevel; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; @@ -26,14 +27,9 @@ import com.cloud.agent.api.to.SwiftTO; */ public class DeleteSnapshotBackupCommand extends SnapshotCommand { @LogLevel(Log4jLevel.Off) - private SwiftTO swift; - private S3TO s3; + private DataStoreTO store; private Boolean all; - public SwiftTO getSwift() { - return swift; - } - public Boolean isAll() { return all; } @@ -42,12 +38,8 @@ public class DeleteSnapshotBackupCommand extends SnapshotCommand { this.all = all; } - public void setSwift(SwiftTO swift) { - this.swift = swift; - } - - public S3TO getS3() { - return s3; + public DataStoreTO getDataStore(){ + return store; } protected DeleteSnapshotBackupCommand() { @@ -78,8 +70,7 @@ public class DeleteSnapshotBackupCommand extends SnapshotCommand { * @param backupUUID The VHD which has to be deleted * @param childUUID The child VHD file of the backup whose parent is reset to its grandparent. */ - public DeleteSnapshotBackupCommand(SwiftTO swift, - S3TO s3, + public DeleteSnapshotBackupCommand(DataStoreTO store, String secondaryStoragePoolURL, Long dcId, Long accountId, @@ -87,8 +78,7 @@ public class DeleteSnapshotBackupCommand extends SnapshotCommand { String backupUUID, Boolean all) { super(null, secondaryStoragePoolURL, backupUUID, null, dcId, accountId, volumeId); - setSwift(swift); - this.s3 = s3; + this.store = store; setAll(all); } } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index b47421031be..6003fac008b 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -265,22 +265,22 @@ SecondaryStorageResource { break; } } - + if (destFile == null) { - return new CopyCmdAnswer("Can't find template"); + return new CopyCmdAnswer("Can't find template"); } - + DataTO newDestTO = null; - + if (destData.getObjectType() == DataObjectType.TEMPLATE) { TemplateObjectTO newTemplTO = new TemplateObjectTO(); newTemplTO.setPath(destPath + File.separator + destFile.getName()); newTemplTO.setName(destFile.getName()); newDestTO = newTemplTO; } else { - return new CopyCmdAnswer("not implemented yet"); + return new CopyCmdAnswer("not implemented yet"); } - + return new CopyCmdAnswer(newDestTO); } catch (Exception e) { @@ -1145,45 +1145,40 @@ SecondaryStorageResource { Long accountId = cmd.getAccountId(); Long volumeId = cmd.getVolumeId(); String name = cmd.getSnapshotUuid(); - try { - SwiftTO swift = cmd.getSwift(); - S3TO s3 = cmd.getS3(); - if (swift == null) { - final String result = deleteSnapshotBackupFromLocalFileSystem( - secondaryStorageUrl, accountId, volumeId, name, - cmd.isAll()); - if (result != null) { - s_logger.warn(result); - return new Answer(cmd, false, result); - } - } else if (s3 != null) { - final String result = deleteSnapshotBackupfromS3(s3, - secondaryStorageUrl, accountId, volumeId, name, - cmd.isAll()); - if (result != null) { - s_logger.warn(result); - return new Answer(cmd, false, result); - } - } else { - String filename; - if (cmd.isAll()) { - filename = ""; - } else { - filename = name; - } - String result = swiftDelete(swift, "V-" + volumeId.toString(), filename); - if (result != null) { - String errMsg = "failed to delete snapshot " + filename + " , err=" + result; - s_logger.warn(errMsg); - return new Answer(cmd, false, errMsg); - } + DataStoreTO dstore = cmd.getDataStore(); + if ( dstore instanceof NfsTO ){ + final String result = deleteSnapshotBackupFromLocalFileSystem( + secondaryStorageUrl, accountId, volumeId, name, + cmd.isAll()); + if (result != null) { + s_logger.warn(result); + return new Answer(cmd, false, result); } - return new Answer(cmd, true, "success"); - } catch (Exception e) { - String errMsg = cmd + " Command failed due to " + e.toString(); - s_logger.warn(errMsg, e); - return new Answer(cmd, false, errMsg); + } else if (dstore instanceof S3TO ){ + final String result = deleteSnapshotBackupfromS3((S3TO)dstore, + secondaryStorageUrl, accountId, volumeId, name, + cmd.isAll()); + if (result != null) { + s_logger.warn(result); + return new Answer(cmd, false, result); + } + } else if (dstore instanceof SwiftTO ){ + String filename; + if (cmd.isAll()) { + filename = ""; + } else { + filename = name; + } + String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename); + if (result != null) { + String errMsg = "failed to delete snapshot " + filename + " , err=" + result; + s_logger.warn(errMsg); + return new Answer(cmd, false, errMsg); + } + } else { + return new Answer(cmd, false, "Unsupported image data store: " + dstore); } + return new Answer(cmd, true, "success"); } Map swiftListTemplate(SwiftTO swift) { @@ -1425,8 +1420,7 @@ SecondaryStorageResource { return new Answer(cmd, false, details); } return new Answer(cmd, true, null); - } - else if (dstore instanceof S3TO ){ + } else if (dstore instanceof S3TO ){ final S3TO s3 = (S3TO)dstore; final Long accountId = cmd.getAccountId(); final Long templateId = cmd.getTemplateId(); @@ -1458,8 +1452,7 @@ SecondaryStorageResource { s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } - } - else if (dstore instanceof SwiftTO){ + } else if (dstore instanceof SwiftTO){ SwiftTO swift = (SwiftTO)dstore; String container = "T-" + cmd.getTemplateId(); String object = ""; @@ -1477,8 +1470,7 @@ SecondaryStorageResource { s_logger.warn(errMsg, e); return new Answer(cmd, false, errMsg); } - } - else{ + } else{ return new Answer(cmd, false, "Unsupported image data store: " + dstore); } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index b8a7760c783..e22cfb9b3cc 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -48,7 +48,7 @@ public class SnapshotObject implements SnapshotInfo { private SnapshotVO snapshot; private DataStore store; @Inject - protected SnapshotDao snapshotDao; + protected SnapshotDao snapshotDao; @Inject protected VolumeDao volumeDao; @Inject protected VolumeDataFactory volFactory; @@ -56,14 +56,14 @@ public class SnapshotObject implements SnapshotInfo { @Inject ObjectInDataStoreManager ojbectInStoreMgr; public SnapshotObject() { - + } - + protected void configure(SnapshotVO snapshot, DataStore store) { this.snapshot = snapshot; this.store = store; } - + public static SnapshotObject getSnapshotObject(SnapshotVO snapshot, DataStore store) { SnapshotObject snapObj = ComponentContext.inject(SnapshotObject.class); snapObj.configure(snapshot, store); @@ -151,7 +151,7 @@ public class SnapshotObject implements SnapshotInfo { public String getPath() { return this.snapshot.getPath(); } - + public void setPath(String path) { this.snapshot.setPath(path); } @@ -195,7 +195,7 @@ public class SnapshotObject implements SnapshotInfo { public long getDomainId() { return this.snapshot.getDomainId(); } - + public void setPrevSnapshotId(Long id) { this.snapshot.setPrevSnapshotId(id); } @@ -204,7 +204,7 @@ public class SnapshotObject implements SnapshotInfo { public Long getDataCenterId() { return this.snapshot.getDataCenterId(); } - + public void processEvent(Snapshot.Event event) throws NoTransitionException { stateMachineMgr.processEvent(this.snapshot, event); @@ -214,15 +214,19 @@ public class SnapshotObject implements SnapshotInfo { public Long getPrevSnapshotId() { return this.snapshot.getPrevSnapshotId(); } - + public void setBackupSnapshotId(String id) { this.snapshot.setBackupSnapshotId(id); } - + public String getBackupSnapshotId() { return this.snapshot.getBackupSnapshotId(); } + public SnapshotVO getSnapshotVO(){ + return this.snapshot; + } + @Override public DataTO getTO() { // TODO Auto-generated method stub @@ -232,6 +236,6 @@ public class SnapshotObject implements SnapshotInfo { @Override public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) { // TODO Auto-generated method stub - + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 633e193b939..6674880525e 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -44,6 +44,8 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -89,6 +91,8 @@ public class SnapshotServiceImpl implements SnapshotService { @Inject protected SnapshotDao _snapshotDao; @Inject + protected SnapshotDataStoreDao _snapshotStoreDao; + @Inject private ResourceManager _resourceMgr; @Inject protected SnapshotManager snapshotMgr; @@ -461,9 +465,14 @@ public class SnapshotServiceImpl implements SnapshotService { @DB protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { - DataStore store = objInStoreMgr.findStore(snapshot.getId(), DataObjectType.SNAPSHOT, DataStoreRole.Image); + SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId()); + if ( snapshotStore == null ){ + s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); + return false; + } + DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); if (store == null) { - s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); + s_logger.debug("Can't find mage store " + snapshotStore.getDataStoreId()); return false; } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 4f8096c8c1a..20ddd903ab0 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -44,6 +44,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -320,43 +321,44 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - Long snapshotId = data.getId(); - SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId); - CommandResult result = new CommandResult(); + SnapshotObject snapshotObj = (SnapshotObject)data; + DataStore secStore = snapshotObj.getDataStore(); + CommandResult result = new CommandResult(); + SnapshotVO snapshot = snapshotObj.getSnapshotVO(); + if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotId); + s_logger.debug("Destroying snapshot " + snapshotObj.getId() + " backup failed due to unable to find snapshot "); + result.setResult("Unable to find snapshot: " + snapshotObj.getId()); callback.complete(result); return; } try { - String secondaryStoragePoolUrl = this.snapshotMgr.getSecondaryStorageURL(snapshot); + String secondaryStoragePoolUrl = secStore.getUri(); Long dcId = snapshot.getDataCenterId(); Long accountId = snapshot.getAccountId(); Long volumeId = snapshot.getVolumeId(); - String backupOfSnapshot = snapshot.getBackupSnapshotId(); + String backupOfSnapshot = snapshotObj.getBackupSnapshotId(); if (backupOfSnapshot == null) { callback.complete(result); return; } - SwiftTO swift = _swiftMgr.getSwiftTO(snapshot.getSwiftId()); - S3TO s3 = _s3Mgr.getS3TO(); DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - swift, s3, secondaryStoragePoolUrl, dcId, accountId, volumeId, + secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId, backupOfSnapshot, false); - Answer answer = agentMgr.sendToSSVM(dcId, cmd); + EndPoint ep = _epSelector.select(secStore); + Answer answer = ep.sendMessage(cmd); if ((answer != null) && answer.getResult()) { snapshot.setBackupSnapshotId(null); - snapshotDao.update(snapshotId, snapshot); + snapshotDao.update(snapshotObj.getId(), snapshot); } else if (answer != null) { result.setResult(answer.getDetails()); } } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotId + ": " + e.toString()); + s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); result.setResult(e.toString()); } callback.complete(result); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 3bbbb70e7de..740dcdcf930 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -279,48 +280,50 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - Long snapshotId = data.getId(); - SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId); - CommandResult result = new CommandResult(); - if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotId); - callback.complete(result); - return; - } + SnapshotObject snapshotObj = (SnapshotObject)data; + DataStore secStore = snapshotObj.getDataStore(); + CommandResult result = new CommandResult(); + SnapshotVO snapshot = snapshotObj.getSnapshotVO(); - try { - String secondaryStoragePoolUrl = this.snapshotMgr.getSecondaryStorageURL(snapshot); - Long dcId = snapshot.getDataCenterId(); - Long accountId = snapshot.getAccountId(); - Long volumeId = snapshot.getVolumeId(); + if (snapshot == null) { + s_logger.debug("Destroying snapshot " + snapshotObj.getId() + " backup failed due to unable to find snapshot "); + result.setResult("Unable to find snapshot: " + snapshotObj.getId()); + callback.complete(result); + return; + } - String backupOfSnapshot = snapshot.getBackupSnapshotId(); - if (backupOfSnapshot == null) { - callback.complete(result); - return; - } - SwiftTO swift = _swiftMgr.getSwiftTO(snapshot.getSwiftId()); - S3TO s3 = _s3Mgr.getS3TO(); + try { + String secondaryStoragePoolUrl = secStore.getUri(); + Long dcId = snapshot.getDataCenterId(); + Long accountId = snapshot.getAccountId(); + Long volumeId = snapshot.getVolumeId(); - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - swift, s3, secondaryStoragePoolUrl, dcId, accountId, volumeId, - backupOfSnapshot, false); - Answer answer = agentMgr.sendToSSVM(dcId, cmd); + String backupOfSnapshot = snapshotObj.getBackupSnapshotId(); + if (backupOfSnapshot == null) { + callback.complete(result); + return; + } - if ((answer != null) && answer.getResult()) { - snapshot.setBackupSnapshotId(null); - snapshotDao.update(snapshotId, snapshot); - } else if (answer != null) { - result.setResult(answer.getDetails()); - } - } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotId + ": " + e.toString()); - result.setResult(e.toString()); - } - callback.complete(result); + DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( + secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId, + backupOfSnapshot, false); + EndPoint ep = _epSelector.select(secStore); + Answer answer = ep.sendMessage(cmd); + + if ((answer != null) && answer.getResult()) { + snapshot.setBackupSnapshotId(null); + snapshotDao.update(snapshotObj.getId(), snapshot); + } else if (answer != null) { + result.setResult(answer.getDetails()); + } + } catch (Exception e) { + s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); + result.setResult(e.toString()); + } + callback.complete(result); } + @Override public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 9ec73e65a5c..00ed2c5a411 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -273,46 +274,47 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - Long snapshotId = data.getId(); - SnapshotVO snapshot = this.snapshotDao.findByIdIncludingRemoved(snapshotId); - CommandResult result = new CommandResult(); - if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotId + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotId); - callback.complete(result); - return; - } + SnapshotObject snapshotObj = (SnapshotObject)data; + DataStore secStore = snapshotObj.getDataStore(); + CommandResult result = new CommandResult(); + SnapshotVO snapshot = snapshotObj.getSnapshotVO(); - try { - String secondaryStoragePoolUrl = this.snapshotMgr.getSecondaryStorageURL(snapshot); - Long dcId = snapshot.getDataCenterId(); - Long accountId = snapshot.getAccountId(); - Long volumeId = snapshot.getVolumeId(); + if (snapshot == null) { + s_logger.debug("Destroying snapshot " + snapshotObj.getId() + " backup failed due to unable to find snapshot "); + result.setResult("Unable to find snapshot: " + snapshotObj.getId()); + callback.complete(result); + return; + } - String backupOfSnapshot = snapshot.getBackupSnapshotId(); - if (backupOfSnapshot == null) { - callback.complete(result); - return; - } - SwiftTO swift = _swiftMgr.getSwiftTO(snapshot.getSwiftId()); - S3TO s3 = _s3Mgr.getS3TO(); + try { + String secondaryStoragePoolUrl = secStore.getUri(); + Long dcId = snapshot.getDataCenterId(); + Long accountId = snapshot.getAccountId(); + Long volumeId = snapshot.getVolumeId(); - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - swift, s3, secondaryStoragePoolUrl, dcId, accountId, volumeId, - backupOfSnapshot, false); - Answer answer = agentMgr.sendToSSVM(dcId, cmd); + String backupOfSnapshot = snapshotObj.getBackupSnapshotId(); + if (backupOfSnapshot == null) { + callback.complete(result); + return; + } - if ((answer != null) && answer.getResult()) { - snapshot.setBackupSnapshotId(null); - snapshotDao.update(snapshotId, snapshot); - } else if (answer != null) { - result.setResult(answer.getDetails()); - } - } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotId + ": " + e.toString()); - result.setResult(e.toString()); - } - callback.complete(result); + DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( + secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId, + backupOfSnapshot, false); + EndPoint ep = _epSelector.select(secStore); + Answer answer = ep.sendMessage(cmd); + + if ((answer != null) && answer.getResult()) { + snapshot.setBackupSnapshotId(null); + snapshotDao.update(snapshotObj.getId(), snapshot); + } else if (answer != null) { + result.setResult(answer.getDetails()); + } + } catch (Exception e) { + s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); + result.setResult(e.toString()); + } + callback.complete(result); } @Override diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 624d1d5af95..4fa683460b8 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -33,11 +33,14 @@ import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotPoliciesCmd; import org.apache.cloudstack.api.command.user.snapshot.ListSnapshotsCmd; 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.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; @@ -198,6 +201,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Inject SnapshotService snapshotSrv; @Inject VolumeDataFactory volFactory; @Inject SnapshotDataFactory snapshotFactory; + @Inject EndPointSelector _epSelector; private int _totalRetries; @@ -666,47 +670,18 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, // This volume doesn't have any snapshots. Nothing do delete. continue; } - List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId); - SwiftTO swift = _swiftMgr.getSwiftTO(); - S3TO s3 = _s3Mgr.getS3TO(); - - checkObjectStorageConfiguration(swift, s3); - - if (swift == null && s3 == null) { - for (HostVO ssHost : ssHosts) { - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - null, null, ssHost.getStorageUrl(), dcId, - accountId, volumeId, "", true); - Answer answer = null; - try { - answer = _agentMgr.sendToSSVM(dcId, cmd); - } catch (Exception e) { - s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on secondary storage " + ssHost.getStorageUrl()); - } - if ((answer != null) && answer.getResult()) { - s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId); - } else { - success = false; - if (answer != null) { - s_logger.error(answer.getDetails()); - } - } - } - } else { - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - swift, s3, "", dcId, accountId, volumeId, "", true); - Answer answer = null; - try { - answer = _agentMgr.sendToSSVM(dcId, cmd); - } catch (Exception e) { - final String storeType = s3 != null ? "S3" : "swift"; - s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on " + storeType); - } + List ssHosts = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId)); + for (DataStore ssHost : ssHosts) { + DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(ssHost.getTO(), ssHost.getUri(), dcId, accountId, volumeId, "", + true); + EndPoint ep = _epSelector.select(ssHost); + Answer answer = ep.sendMessage(cmd); if ((answer != null) && answer.getResult()) { s_logger.debug("Deleted all snapshots for volume: " + volumeId + " under account: " + accountId); } else { success = false; if (answer != null) { + s_logger.warn("Failed to delete all snapshot for volume " + volumeId + " on secondary storage " + ssHost.getUri()); s_logger.error(answer.getDetails()); } } From 79151f5f5d3e970993ecdcd7ded458bcabc29e48 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 24 Apr 2013 17:45:32 -0700 Subject: [PATCH 063/303] Remove sendToSSVM reference from SnapshotManagerImpl and TemplateManagerImpl. --- .../CloudStackImageStoreDriverImpl.java | 11 +-- .../storage/snapshot/SnapshotManagerImpl.java | 12 +-- .../cloud/template/TemplateManagerImpl.java | 75 +------------------ 3 files changed, 11 insertions(+), 87 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 20ddd903ab0..0ef735c8292 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -310,12 +310,13 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { callback.complete(result); } - VMTemplateZoneVO templateZone = templateZoneDao.findByZoneTemplate(sZoneId, templateId); - - if (templateZone != null) { - templateZoneDao.remove(templateZone.getId()); + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } } - } + } } } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 4fa683460b8..11408f9a779 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -319,20 +319,14 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, return snapshot; } - private void checkObjectStorageConfiguration(SwiftTO swift, S3TO s3) { - - if (swift != null && s3 != null) { - throw new CloudRuntimeException( - "Swift and S3 are not simultaneously supported for snapshot backup."); - } - - } @Override public void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId) { DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(secondaryStoragePoolUrl, dcId, accountId, volumeId); try { - Answer ans = _agentMgr.sendToSSVM(dcId, cmd); + DataStore store = this.dataStoreMgr.getImageStore(dcId); + EndPoint ep = _epSelector.select(store); + Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { s_logger.warn("DeleteSnapshotsDirCommand failed due to " + ans.getDetails() + " volume id: " + volumeId); } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index eb628a9fab5..fb226c388b4 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -530,61 +530,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } - - String uploadTemplateToSwiftFromSecondaryStorage(VMTemplateHostVO templateHostRef) { - Long templateId = templateHostRef.getTemplateId(); - VMTemplateVO template = _tmpltDao.findById(templateId); - if (template == null) { - String errMsg = " Can not find template " + templateId; - s_logger.warn(errMsg); - return errMsg; - } - - if (template.getTemplateType() == TemplateType.PERHOST) { - return null; - } - - SwiftTO swift = _swiftMgr.getSwiftTO(); - if (swift == null) { - String errMsg = " There is no Swift in this setup "; - s_logger.warn(errMsg); - return errMsg; - } - - HostVO secHost = _hostDao.findById(templateHostRef.getHostId()); - if (secHost == null) { - String errMsg = "Can not find secondary storage " + templateHostRef.getHostId(); - s_logger.warn(errMsg); - return errMsg; - } - - uploadTemplateToSwiftFromSecondaryStorageCommand cmd = new uploadTemplateToSwiftFromSecondaryStorageCommand(swift, secHost.getName(), secHost.getDataCenterId(), template.getAccountId(), - templateId, _primaryStorageDownloadWait); - Answer answer = null; - try { - answer = _agentMgr.sendToSSVM(secHost.getDataCenterId(), cmd); - if (answer == null || !answer.getResult()) { - if (template.getTemplateType() != TemplateType.SYSTEM) { - String errMsg = "Failed to upload template " + templateId + " to Swift from secondary storage due to " + ((answer == null) ? "null" : answer.getDetails()); - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); - } - return null; - } - String path = templateHostRef.getInstallPath(); - int index = path.lastIndexOf('/'); - path = path.substring(index + 1); - VMTemplateSwiftVO tmpltSwift = new VMTemplateSwiftVO(swift.getId(), templateHostRef.getTemplateId(), new Date(), path, templateHostRef.getSize(), templateHostRef.getPhysicalSize()); - _tmpltSwiftDao.persist(tmpltSwift); - _swiftMgr.propagateTemplateOnAllZones(templateHostRef.getTemplateId()); - } catch (Exception e) { - String errMsg = "Failed to upload template " + templateId + " to Swift from secondary storage due to " + e.toString(); - s_logger.warn(errMsg); - throw new CloudRuntimeException(errMsg); - } - return null; - } - @Override @DB public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) { VMTemplateVO template = _tmpltDao.findById(templ.getId(), true); @@ -1182,30 +1127,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template.getFormat() != ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid iso."); } - if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) { - _swiftMgr.deleteIso(cmd); - } - if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) { - _s3Mgr.deleteTemplate(caller.getAccountId(), templateId); - } - if (zoneId != null && (_ssvmMgr.findSecondaryStorageHost(zoneId) == null)) { - throw new InvalidParameterValueException("Failed to find a secondary storage host in the specified zone."); + if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) { + throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); } TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); boolean result = adapter.delete(profile); if (result) { - if (cmd.getZoneId() == null - && (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) { - List templateZones = _tmpltZoneDao - .listByZoneTemplate(null, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - _tmpltZoneDao.remove(templateZone.getId()); - } - } - } return true; } else { throw new CloudRuntimeException("Failed to delete ISO"); From 4029e7af444c681936935eee85873d2f43d1146e Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 24 Apr 2013 18:53:36 -0700 Subject: [PATCH 064/303] refactor data motion service for volumes --- .../api/storage/CreateCmdResult.java | 18 ++- .../storage/to/TemplateObjectTO.java | 6 +- .../cloudstack/storage/to/VolumeObjectTO.java | 9 +- .../motion/AncientDataMotionStrategy.java | 106 ++++-------------- .../storage/volume/VolumeObject.java | 13 +++ .../storage/volume/VolumeServiceImpl.java | 21 ++-- .../resource/XenServerStorageResource.java | 78 ++++++++++++- .../driver/SampleImageStoreDriverImpl.java | 2 +- 8 files changed, 144 insertions(+), 109 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java index b6d5b689951..4b78e54bb90 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java @@ -18,20 +18,26 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.agent.api.Answer; + public class CreateCmdResult extends CommandResult { private String path; - private Long size; - public CreateCmdResult(String path, Long size) { + private Answer answer; + public CreateCmdResult(String path, Answer answer) { super(); this.path = path; - this.size = size; } public String getPath() { return this.path; } - - public Long getSize() { - return this.size; + + public Answer getAnswer() { + return answer; } + + public void setAnswer(Answer answer) { + this.answer = answer; + } + } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 1e72ea0bdea..3a3564aaefa 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -28,7 +28,7 @@ public class TemplateObjectTO implements DataTO { private String path; private String uuid; private DiskFormat diskType; - private ImageStoreTO imageDataStore; + private DataStoreTO imageDataStore; private String name; public TemplateObjectTO() { @@ -38,7 +38,7 @@ public class TemplateObjectTO implements DataTO { this.path = template.getUri(); this.uuid = template.getUuid(); //this.diskType = template.getDiskType(); - this.imageDataStore = new ImageStoreTO((ImageStoreInfo)template.getDataStore()); + this.imageDataStore = template.getDataStore().getTO(); this.name = template.getUniqueName(); } @@ -55,7 +55,7 @@ public class TemplateObjectTO implements DataTO { return this.diskType; } - public ImageStoreTO getImageDataStore() { + public DataStoreTO getImageDataStore() { return this.imageDataStore; } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 1fecf68c091..bf1bb3c8047 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -18,16 +18,17 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; +import com.cloud.agent.api.to.DataStoreTO; + public class VolumeObjectTO implements DataTO { private String uuid; private VolumeType volumeType; private DiskFormat diskType; - private PrimaryDataStoreTO dataStore; + private DataStoreTO dataStore; private String name; private long size; private String path; @@ -42,7 +43,7 @@ public class VolumeObjectTO implements DataTO { //this.volumeType = volume.getType(); //this.diskType = volume.getDiskType(); if (volume.getDataStore() != null) { - this.dataStore = new PrimaryDataStoreTO((PrimaryDataStoreInfo)volume.getDataStore()); + this.dataStore = volume.getDataStore().getTO(); } else { this.dataStore = null; } @@ -66,7 +67,7 @@ public class VolumeObjectTO implements DataTO { return this.diskType; } - public PrimaryDataStoreTO getDataStore() { + public DataStoreTO getDataStore() { return this.dataStore; } 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 index 84d2b16e91c..6a37c9dd035 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -141,47 +141,24 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @DB protected Answer copyVolumeFromImage(DataObject srcData, DataObject destData) { - String value = configDao.getValue(Config.RecreateSystemVmEnabled.key()); + String value = configDao.getValue(Config.CopyVolumeWait.key()); int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - VolumeDataStoreVO volumeStoreVO = volumeStoreDao.findByVolume(srcData - .getId()); - DataStore srcStore = srcData.getDataStore(); - String[] volumePath = volumeStoreVO.getInstallPath().split("/"); - String volumeUUID = volumePath[volumePath.length - 1].split("\\.")[0]; - StoragePool destPool = (StoragePool) destData.getDataStore(); - CopyVolumeCommand cvCmd = new CopyVolumeCommand(srcData.getId(), - volumeUUID, destPool, srcStore.getUri(), 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 (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + //need to copy it to image cache store + DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(cacheData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } else { + //handle copy it to/from cache store + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; } - - 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); - volumeStoreDao.remove(volumeStoreVO.getId()); - txn.commit(); - return cvAnswer; } private Answer copyTemplate(DataObject srcData, DataObject destData) { @@ -195,7 +172,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { Answer answer = ep.sendMessage(cmd); return answer; } else { - //handle copy it to cache store + //handle copy it to/from cache store CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait); EndPoint ep = selector.select(srcData, destData); Answer answer = ep.sendMessage(cmd); @@ -326,56 +303,15 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } 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()); + String value = configDao.getValue(Config.CopyVolumeWait.key()); 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; + DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(cacheData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index d5f5fbcf6a9..41e35607223 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -29,10 +29,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Volume; @@ -52,6 +55,8 @@ public class VolumeObject implements VolumeInfo { @Inject VolumeDao volumeDao; @Inject + VolumeDataStoreDao volumeStoreDao; + @Inject ObjectInDataStoreManager ojbectInStoreMgr; private Object payload; @@ -357,6 +362,14 @@ public class VolumeObject implements VolumeInfo { vol.setSize(newVol.getSize()); volumeDao.update(vol.getId(), vol); } + } else if (this.dataStore.getRole() == DataStoreRole.Image) { + if (answer instanceof DownloadAnswer) { + DownloadAnswer dwdAnswer = (DownloadAnswer)answer; + VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); + volStore.setInstallPath(dwdAnswer.getInstallPath()); + volStore.setChecksum(dwdAnswer.getCheckSum()); + this.volumeStoreDao.update(volStore.getId(), volStore); + } } this.processEvent(event); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 3bf20369825..47d99bd8612 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -621,7 +621,7 @@ public class VolumeServiceImpl implements VolumeService { return null; } srcVolume.processEvent(Event.OperationSuccessed); - destVolume.processEvent(Event.OperationSuccessed); + destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); AsyncCallFuture destroyFuture = this.expungeVolumeAsync(srcVolume); destroyFuture.get(); future.complete(res); @@ -639,25 +639,28 @@ public class VolumeServiceImpl implements VolumeService { public AsyncCallFuture registerVolume(VolumeInfo volume, DataStore store) { AsyncCallFuture future = new AsyncCallFuture(); - VolumeObject vo = (VolumeObject) volume; - - CreateVolumeContext context = new CreateVolumeContext(null, vo, future); + DataObject volumeOnStore = store.create(volume); + + volumeOnStore.processEvent(Event.CreateOnlyRequested); + + CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)) .setContext(context); - dataObjectMgr.createAsync(volume, store, caller, true); + store.getDriver().createAsync(volumeOnStore, caller); return future; } protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); + VolumeObject vo = (VolumeObject)context.volume; - /*if (result.isFailed()) { - vo.stateTransit(Volume.Event.OperationFailed); + if (result.isFailed()) { + vo.processEvent(Event.OperationFailed); } else { - vo.stateTransit(Volume.Event.OperationSucceeded); - }*/ + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); + } _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 4c25bfae0a9..9f47e0682a3 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -55,12 +55,15 @@ import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; +import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.DataStoreRole; import com.cloud.utils.exception.CloudRuntimeException; @@ -774,7 +777,75 @@ public class XenServerStorageResource { return new CopyCmdAnswer(e.toString()); } } - + + + protected Answer copyVolumeFromImageCacheToPrimary(DataTO srcData, DataTO destData, int wait) { + Connection conn = hypervisorResource.getConnection(); + VolumeObjectTO srcVolume = (VolumeObjectTO)srcData; + VolumeObjectTO destVolume = (VolumeObjectTO)destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destVolume.getDataStore(); + DataStoreTO srcStore = srcVolume.getDataStore(); + + if (srcStore instanceof NfsTO) { + NfsTO nfsStore = (NfsTO)srcStore; + try { + SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); + String srUuid = primaryStoragePool.getUuid(conn); + String volumePath = nfsStore.getUrl() + ":" + srcVolume.getPath(); + String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait ); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(uuid); + newVol.setSize(srcVolume.getSize()); + + return new CopyCmdAnswer(newVol); + } catch (Exception e) { + String msg = "Catch Exception " + e.getClass().getName() + " due to " + e.toString(); + s_logger.warn(msg, e); + return new CopyCmdAnswer(e.toString()); + } + } + + s_logger.debug("unsupported protocol"); + return new CopyCmdAnswer("unsupported protocol"); + } + + protected Answer copyVolumeFromPrimaryToSecondary(DataTO srcData, DataTO destData, int wait) { + Connection conn = hypervisorResource.getConnection(); + VolumeObjectTO srcVolume = (VolumeObjectTO)srcData; + VolumeObjectTO destVolume = (VolumeObjectTO)destData; + DataStoreTO destStore = destVolume.getDataStore(); + + if (destStore instanceof NfsTO) { + SR secondaryStorage = null; + try { + NfsTO nfsStore = (NfsTO)destStore; + URI uri = new URI(nfsStore.getUrl()); + // Create the volume folder + if (!hypervisorResource.createSecondaryStorageFolder(conn, uri.getHost() + ":" + uri.getPath(), destVolume.getPath())) { + throw new InternalErrorException("Failed to create the volume folder."); + } + + // Create a SR for the volume UUID folder + secondaryStorage = hypervisorResource.createNfsSRbyURI(conn, new URI(nfsStore.getUrl() + destVolume.getPath()), false); + // Look up the volume on the source primary storage pool + VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); + // Copy the volume to secondary storage + VDI destVdi = hypervisorResource.cloudVDIcopy(conn, srcVdi, secondaryStorage, wait); + String destVolumeUUID = destVdi.getUuid(conn); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(destVolumeUUID); + newVol.setSize(srcVolume.getSize()); + return new CopyCmdAnswer(newVol); + } catch (Exception e) { + s_logger.debug("Failed to copy volume to secondary: " + e.toString()); + return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString()); + } finally { + hypervisorResource.removeSR(conn, secondaryStorage); + } + } + return new CopyCmdAnswer("unsupported protocol"); + } protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); @@ -788,6 +859,11 @@ public class XenServerStorageResource { } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { //clone template to a volume return cloneVolumeFromBaseTemplate(srcData, destData); + } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.ImageCache) { + //copy volume from image cache to primary + return copyVolumeFromImageCacheToPrimary(srcData, destData, cmd.getWait()); + } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { + return copyVolumeFromPrimaryToSecondary(srcData, destData, cmd.getWait()); } return new Answer(cmd, false, "not implemented yet"); diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index acf679679dc..91f9cd0abe6 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -101,7 +101,7 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { if (answer.getResult()) { //update imagestorevo - result = new CreateCmdResult(answer.getPath(), answer.getSize()); + result = new CreateCmdResult(answer.getPath(), null); } else { result.setResult(answer.getDetails()); } From de27f0ff53275d31321e32b32cc8942f508c2220 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 25 Apr 2013 16:49:46 -0700 Subject: [PATCH 065/303] Clean up DownloadMonitor and TemplateManagerImpl. --- .../storage/download/DownloadMonitor.java | 10 --- .../storage/download/DownloadMonitorImpl.java | 64 ------------------- .../cloud/template/TemplateManagerImpl.java | 13 ---- 3 files changed, 87 deletions(-) diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index 7bc210f2c83..42fb9d277b1 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -21,10 +21,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.exception.StorageUnavailableException; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VolumeVO; import com.cloud.utils.component.Manager; /** @@ -33,16 +30,9 @@ import com.cloud.utils.component.Manager; */ public interface DownloadMonitor extends Manager{ - // when ssvm is not available yet - public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback); public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback); - //public void cancelAllDownloads(Long templateId); - - //public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore Store) - // throws StorageUnavailableException; - public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 2afa4e668c9..de43e4ba5cf 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -51,7 +51,6 @@ import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; -import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.configuration.Config; @@ -68,7 +67,6 @@ import com.cloud.storage.Volume; import com.cloud.storage.VolumeHostVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; @@ -378,68 +376,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } - @Override - public void downloadBootstrapSysTemplateToStorage(VMTemplateVO template, DataStore store, AsyncCompletionCallback callback) { - boolean downloadJobExists = false; - TemplateDataStoreVO vmTemplateStore = null; - - vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); - if (vmTemplateStore == null) { - // This method can be invoked other places, for example, - // handleTemplateSync, in that case, vmTemplateStore may be null - vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, - VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUrl()); - _vmTemplateStoreDao.persist(vmTemplateStore); - } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { - downloadJobExists = true; - } - - Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); - String secUrl = store.getUri(); - if (vmTemplateStore != null) { - start(); - DownloadSystemTemplateCommand dcmd = new DownloadSystemTemplateCommand(store.getTO(), secUrl, template, maxTemplateSizeInBytes); - dcmd.setProxy(getHttpProxy()); - // TODO: handle S3 download progress - // if (downloadJobExists) { - // dcmd = new DownloadProgressCommand(dcmd, - // vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); - // } - if (vmTemplateStore.isCopy()) { - dcmd.setCreds(TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd); - } - EndPoint endPoint = _epSelector.select(this.tmplFactory.getTemplate(template.getId(), store)); - if (endPoint == null) { - s_logger.warn("There is no endpoint to send download template command"); - return; - } - // TODO: wait for Edison's code to pass a listener to - // LocalHostEndPoint - /* - DownloadListener dl = new DownloadListener(ssAhost, store, template, _timer, _vmTemplateStoreDao, vmTemplateStore.getId(), this, dcmd, - _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, callback); - if (downloadJobExists) { - // due to handling existing download job issues, we still keep - // downloadState in template_store_ref to avoid big change in - // DownloadListener to use - // new ObjectInDataStore.State transition. TODO: fix this later - // to be able to remove downloadState from template_store_ref. - dl.setCurrState(vmTemplateStore.getDownloadState()); - } - DownloadListener old = null; - synchronized (_listenerTemplateMap) { - old = _listenerTemplateMap.put(vmTemplateStore, dl); - } - if (old != null) { - old.abandon(); - } - */ - // endPoint.sendMessageAsync(dcmd, callback); - endPoint.sendMessage(dcmd); // wait for Edison's callback code - - } - } - @Override public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback) { long templateId = template.getId(); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index fb226c388b4..de69c12376a 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -22,10 +22,8 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Random; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -81,10 +79,7 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.uploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.to.SwiftTO; - import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -138,9 +133,7 @@ import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeManager; import com.cloud.storage.VolumeVO; @@ -157,9 +150,7 @@ import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.upload.UploadMonitor; import com.cloud.template.TemplateAdapter.TemplateAdapterType; @@ -216,10 +207,6 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject VolumeDao _volumeDao; @Inject SnapshotDao _snapshotDao; @Inject - SwiftManager _swiftMgr; - @Inject - S3Manager _s3Mgr; - @Inject VMTemplateSwiftDao _tmpltSwiftDao; @Inject VMTemplateS3Dao _vmS3TemplateDao; From 91bfbdf1c4b0c514cd167c99a8456155e64b70af Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 26 Apr 2013 12:25:06 -0700 Subject: [PATCH 066/303] Handle ListTemplateCommand in NfsSecondaryStorageResource for various data store provider. --- .../api/DeleteTemplateFromS3Command.java | 106 -- .../api/storage/DeleteTemplateCommand.java | 3 +- .../DownloadSystemTemplateCommand.java | 15 + .../api/storage/ListTemplateCommand.java | 22 +- .../LocalNfsSecondaryStorageResource.java | 19 +- .../LocalSecondaryStorageResource.java | 13 +- .../resource/NfsSecondaryStorageResource.java | 907 ++++++++---------- .../storage/image/TemplateServiceImpl.java | 2 +- .../CloudStackImageStoreDriverImpl.java | 2 +- .../driver/S3ImageStoreDriverImpl.java | 2 +- .../driver/SwiftImageStoreDriverImpl.java | 2 +- .../SamplePrimaryDataStoreDriverImpl.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../src/com/cloud/storage/s3/S3Manager.java | 2 +- .../com/cloud/storage/s3/S3ManagerImpl.java | 65 -- utils/src/com/cloud/utils/S3Utils.java | 29 + 16 files changed, 490 insertions(+), 703 deletions(-) delete mode 100644 api/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java diff --git a/api/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java b/api/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java deleted file mode 100644 index 278669b2c97..00000000000 --- a/api/src/com/cloud/agent/api/DeleteTemplateFromS3Command.java +++ /dev/null @@ -1,106 +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 com.cloud.agent.api; - -import com.cloud.agent.api.to.S3TO; - -public class DeleteTemplateFromS3Command extends Command { - - private S3TO s3; - private Long templateId; - private Long accountId; - - protected DeleteTemplateFromS3Command() { - super(); - } - - public DeleteTemplateFromS3Command(final S3TO s3, final Long accountId, - final Long templateId) { - - super(); - - this.s3 = s3; - this.accountId = accountId; - this.templateId = templateId; - - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((accountId == null) ? 0 : accountId.hashCode()); - result = prime * result + ((s3 == null) ? 0 : s3.hashCode()); - result = prime * result - + ((templateId == null) ? 0 : templateId.hashCode()); - return result; - } - - @Override - public boolean equals(Object thatObject) { - - if (this == thatObject) { - return true; - } - - if (thatObject == null) { - return false; - } - - if (getClass() != thatObject.getClass()) { - return false; - } - - final DeleteTemplateFromS3Command thatCommand = (DeleteTemplateFromS3Command) thatObject; - - if (!(accountId == thatCommand.accountId) - || (this.accountId != null && this.accountId - .equals(thatCommand.accountId))) { - return false; - } - - if (!(templateId == thatCommand.templateId) - || (this.templateId != null && this.templateId - .equals(thatCommand.templateId))) { - return false; - } - - return true; - - } - - public S3TO getS3() { - return s3; - } - - public Long getTemplateId() { - return templateId; - } - - public Long getAccountId() { - return accountId; - } - - @Override - public boolean executeInSequence() { - return true; - } - -} diff --git a/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java b/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java index 9b874cf5156..f72657c5e8a 100644 --- a/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java @@ -30,8 +30,7 @@ public class DeleteTemplateCommand extends ssCommand { } - public DeleteTemplateCommand(DataStoreTO store, String secUrl, String templatePath, Long templateId, Long accountId) { - this.setSecUrl(secUrl); + public DeleteTemplateCommand(DataStoreTO store, String templatePath, Long templateId, Long accountId) { this.templatePath = templatePath; this.templateId = templateId; this.accountId = accountId; diff --git a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java index d7efcc056e1..6bdd9bcdfbd 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java @@ -51,6 +51,7 @@ public class DownloadSystemTemplateCommand extends Command { private Long accountId; private String url; private Long maxDownloadSizeInBytes; + private String name; protected DownloadSystemTemplateCommand() { } @@ -63,6 +64,7 @@ public class DownloadSystemTemplateCommand extends Command { this.url = secUrl; this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceId = template.getId(); + this.name = template.getUniqueName(); } @@ -73,6 +75,7 @@ public class DownloadSystemTemplateCommand extends Command { this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceId = template.getId(); auth = new PasswordAuth(user, passwd); + this.name = template.getUniqueName(); } @@ -144,6 +147,18 @@ public class DownloadSystemTemplateCommand extends Command { + public String getName() { + return name; + } + + + + public void setName(String name) { + this.name = name; + } + + + @Override public boolean executeInSequence() { // TODO Auto-generated method stub diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java index da25ed56bf3..4a15887a9af 100644 --- a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java @@ -18,37 +18,27 @@ package com.cloud.agent.api.storage; import com.cloud.agent.api.LogLevel; import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.agent.api.to.SwiftTO; +import com.cloud.agent.api.to.DataStoreTO; public class ListTemplateCommand extends StorageCommand { - private String secUrl; @LogLevel(Log4jLevel.Off) - private SwiftTO swift; + private DataStoreTO store; public ListTemplateCommand() { } - public ListTemplateCommand(String secUrl) { - this.secUrl = secUrl; - this.swift = null; + public ListTemplateCommand(DataStoreTO store) { + this.store = store; } - public ListTemplateCommand(SwiftTO swift) { - this.secUrl = null; - this.swift = swift; - } - @Override public boolean executeInSequence() { return true; } - public String getSecUrl() { - return secUrl; - } - public SwiftTO getSwift() { - return swift; + public DataStoreTO getDataStore() { + return store; } } diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index c2583324295..282074c850c 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -9,16 +9,20 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.List; import org.springframework.stereotype.Component; +import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.S3Utils; import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; @@ -62,10 +66,19 @@ public class LocalNfsSecondaryStorageResource extends } final String bucket = s3.getBucketName(); - String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR); + // convention is no / in the end for install path based on S3Utils implementation. + String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); + // template key is + // TEMPLATE_ROOT_DIR/account_id/template_id/template_name + String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR); S3Utils.putObject(s3, in, bucket, key); - return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url, - cmd.getResourceId(), bucket)); + List s3Obj = S3Utils.getDirectory(s3, bucket, path); + if (s3Obj == null || s3Obj.size() == 0) { + return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key); + } else { + return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj.get(0) + .getETag()); + } } else if ( dstore instanceof NfsTO ){ return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates"); diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java index 89d0fe1836e..5e97c1575dd 100644 --- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java @@ -50,6 +50,7 @@ import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.TemplateProp; import com.cloud.utils.component.ComponentContext; +import com.cloud.agent.api.to.NfsTO; public class LocalSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource { private static final Logger s_logger = Logger.getLogger(LocalSecondaryStorageResource.class); @@ -94,7 +95,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements } else if (cmd instanceof ReadyCommand) { return new ReadyAnswer((ReadyCommand)cmd); } else if (cmd instanceof ListTemplateCommand){ - return execute((ListTemplateCommand)cmd); + return execute((ListTemplateCommand)cmd); } else if (cmd instanceof ComputeChecksumCommand){ return execute((ComputeChecksumCommand)cmd); } else { @@ -103,14 +104,14 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements } private Answer execute(ComputeChecksumCommand cmd) { - return new Answer(cmd, false, null); + return new Answer(cmd, false, null); } private Answer execute(ListTemplateCommand cmd) { String root = getRootDir(); Map templateInfos = _dlMgr.gatherTemplateInfo(root); - return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); + return new ListTemplateAnswer(((NfsTO)cmd.getDataStore()).getUrl(), templateInfos); } @Override @@ -213,14 +214,14 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements @Override public void setName(String name) { // TODO Auto-generated method stub - + } @Override public void setConfigParams(Map params) { // TODO Auto-generated method stub - + } @@ -241,6 +242,6 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements @Override public void setRunLevel(int level) { // TODO Auto-generated method stub - + } } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 6003fac008b..0abe1499977 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.storage.resource; -import static com.cloud.utils.S3Utils.deleteDirectory; import static com.cloud.utils.S3Utils.getDirectory; import static com.cloud.utils.StringUtils.join; import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; @@ -52,8 +51,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; @@ -63,7 +64,6 @@ import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.DeleteObjectFromSwiftCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand; -import com.cloud.agent.api.DeleteTemplateFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromS3Command; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; @@ -87,6 +87,7 @@ import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; @@ -105,6 +106,7 @@ import com.cloud.host.Host.Type; import com.cloud.resource.ServerResourceBase; import com.cloud.storage.DataStoreRole; import com.cloud.storage.StorageLayer; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; @@ -122,11 +124,9 @@ import com.cloud.utils.script.OutputInterpreter; import com.cloud.utils.script.Script; import com.cloud.vm.SecondaryStorageVm; -public class NfsSecondaryStorageResource extends ServerResourceBase implements -SecondaryStorageResource { +public class NfsSecondaryStorageResource extends ServerResourceBase implements SecondaryStorageResource { - private static final Logger s_logger = Logger - .getLogger(NfsSecondaryStorageResource.class); + private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class); private static final String TEMPLATE_ROOT_DIR = "template/tmpl"; private static final String SNAPSHOT_ROOT_DIR = "snapshots"; @@ -160,6 +160,7 @@ SecondaryStorageResource { final private String _parent = "/mnt/SecStorage"; final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; + @Override public void disconnected() { } @@ -167,45 +168,45 @@ SecondaryStorageResource { @Override public Answer executeRequest(Command cmd) { if (cmd instanceof DownloadProgressCommand) { - return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand)cmd); + return _dlMgr.handleDownloadCommand(this, (DownloadProgressCommand) cmd); } else if (cmd instanceof DownloadCommand) { - return execute((DownloadCommand)cmd); + return execute((DownloadCommand) cmd); } else if (cmd instanceof UploadCommand) { - return _upldMgr.handleUploadCommand(this, (UploadCommand)cmd); - } else if (cmd instanceof CreateEntityDownloadURLCommand){ - return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand)cmd); - } else if(cmd instanceof DeleteEntityDownloadURLCommand){ - return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand)cmd); + return _upldMgr.handleUploadCommand(this, (UploadCommand) cmd); + } else if (cmd instanceof CreateEntityDownloadURLCommand) { + return _upldMgr.handleCreateEntityURLCommand((CreateEntityDownloadURLCommand) cmd); + } else if (cmd instanceof DeleteEntityDownloadURLCommand) { + return _upldMgr.handleDeleteEntityDownloadURLCommand((DeleteEntityDownloadURLCommand) cmd); } else if (cmd instanceof GetStorageStatsCommand) { - return execute((GetStorageStatsCommand)cmd); + return execute((GetStorageStatsCommand) cmd); } else if (cmd instanceof CheckHealthCommand) { - return new CheckHealthAnswer((CheckHealthCommand)cmd, true); + return new CheckHealthAnswer((CheckHealthCommand) cmd, true); } else if (cmd instanceof DeleteTemplateCommand) { return execute((DeleteTemplateCommand) cmd); } else if (cmd instanceof DeleteVolumeCommand) { return execute((DeleteVolumeCommand) cmd); - }else if (cmd instanceof ReadyCommand) { - return new ReadyAnswer((ReadyCommand)cmd); - } else if (cmd instanceof SecStorageFirewallCfgCommand){ - return execute((SecStorageFirewallCfgCommand)cmd); - } else if (cmd instanceof SecStorageVMSetupCommand){ - return execute((SecStorageVMSetupCommand)cmd); - } else if (cmd instanceof SecStorageSetupCommand){ - return execute((SecStorageSetupCommand)cmd); - } else if (cmd instanceof ComputeChecksumCommand){ - return execute((ComputeChecksumCommand)cmd); - } else if (cmd instanceof ListTemplateCommand){ - return execute((ListTemplateCommand)cmd); - } else if (cmd instanceof ListVolumeCommand){ - return execute((ListVolumeCommand)cmd); - }else if (cmd instanceof downloadSnapshotFromSwiftCommand){ - return execute((downloadSnapshotFromSwiftCommand)cmd); + } else if (cmd instanceof ReadyCommand) { + return new ReadyAnswer((ReadyCommand) cmd); + } else if (cmd instanceof SecStorageFirewallCfgCommand) { + return execute((SecStorageFirewallCfgCommand) cmd); + } else if (cmd instanceof SecStorageVMSetupCommand) { + return execute((SecStorageVMSetupCommand) cmd); + } else if (cmd instanceof SecStorageSetupCommand) { + return execute((SecStorageSetupCommand) cmd); + } else if (cmd instanceof ComputeChecksumCommand) { + return execute((ComputeChecksumCommand) cmd); + } else if (cmd instanceof ListTemplateCommand) { + return execute((ListTemplateCommand) cmd); + } else if (cmd instanceof ListVolumeCommand) { + return execute((ListVolumeCommand) cmd); + } else if (cmd instanceof downloadSnapshotFromSwiftCommand) { + return execute((downloadSnapshotFromSwiftCommand) cmd); } else if (cmd instanceof DownloadSnapshotFromS3Command) { return execute((DownloadSnapshotFromS3Command) cmd); - } else if (cmd instanceof DeleteSnapshotBackupCommand){ - return execute((DeleteSnapshotBackupCommand)cmd); - } else if (cmd instanceof DeleteSnapshotsDirCommand){ - return execute((DeleteSnapshotsDirCommand)cmd); + } else if (cmd instanceof DeleteSnapshotBackupCommand) { + return execute((DeleteSnapshotBackupCommand) cmd); + } else if (cmd instanceof DeleteSnapshotsDirCommand) { + return execute((DeleteSnapshotsDirCommand) cmd); } else if (cmd instanceof downloadTemplateFromSwiftToSecondaryStorageCommand) { return execute((downloadTemplateFromSwiftToSecondaryStorageCommand) cmd); } else if (cmd instanceof uploadTemplateToSwiftFromSecondaryStorageCommand) { @@ -214,130 +215,118 @@ SecondaryStorageResource { return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd); } else if (cmd instanceof DeleteObjectFromSwiftCommand) { return execute((DeleteObjectFromSwiftCommand) cmd); - } else if (cmd instanceof DeleteTemplateFromS3Command) { - return execute((DeleteTemplateFromS3Command) cmd); - } else if (cmd instanceof CleanupSnapshotBackupCommand){ - return execute((CleanupSnapshotBackupCommand)cmd); + } else if (cmd instanceof CleanupSnapshotBackupCommand) { + return execute((CleanupSnapshotBackupCommand) cmd); } else if (cmd instanceof CopyCommand) { - return execute((CopyCommand)cmd); + return execute((CopyCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } } - protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, - DataTO destData, NfsTO destImageStore) { - final String storagePath = destImageStore.getUrl(); - final String destPath = destData.getPath(); + DataTO destData, NfsTO destImageStore) { + final String storagePath = destImageStore.getUrl(); + final String destPath = destData.getPath(); - try { + try { - final File downloadDirectory = _storage - .getFile(determineStorageTemplatePath(storagePath, - destPath)); - downloadDirectory.mkdirs(); + final File downloadDirectory = _storage.getFile(determineStorageTemplatePath(storagePath, destPath)); + downloadDirectory.mkdirs(); - if (!downloadDirectory.exists()) { - final String errMsg = format( - "Unable to create directory " - + "download directory %1$s for download from S3.", downloadDirectory.getName() - ); - s_logger.error(errMsg); - return new CopyCmdAnswer(errMsg); - } + if (!downloadDirectory.exists()) { + final String errMsg = format("Unable to create directory " + "download directory %1$s for download from S3.", + downloadDirectory.getName()); + s_logger.error(errMsg); + return new CopyCmdAnswer(errMsg); + } - List files = getDirectory(s3, s3.getBucketName(), - destPath, - downloadDirectory, new FileNamingStrategy() { - @Override - public String determineFileName(final String key) { - return substringAfterLast(key, S3Utils.SEPARATOR); - } - }); + List files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() { + @Override + public String determineFileName(final String key) { + return substringAfterLast(key, S3Utils.SEPARATOR); + } + }); - //find out template name - File destFile = null; - for (File f : files) { - if (!f.getName().endsWith(".properties")) { - destFile = f; - break; - } - } + // find out template name + File destFile = null; + for (File f : files) { + if (!f.getName().endsWith(".properties")) { + destFile = f; + break; + } + } - if (destFile == null) { - return new CopyCmdAnswer("Can't find template"); - } + if (destFile == null) { + return new CopyCmdAnswer("Can't find template"); + } - DataTO newDestTO = null; + DataTO newDestTO = null; - if (destData.getObjectType() == DataObjectType.TEMPLATE) { - TemplateObjectTO newTemplTO = new TemplateObjectTO(); - newTemplTO.setPath(destPath + File.separator + destFile.getName()); - newTemplTO.setName(destFile.getName()); - newDestTO = newTemplTO; - } else { - return new CopyCmdAnswer("not implemented yet"); - } + if (destData.getObjectType() == DataObjectType.TEMPLATE) { + TemplateObjectTO newTemplTO = new TemplateObjectTO(); + newTemplTO.setPath(destPath + File.separator + destFile.getName()); + newTemplTO.setName(destFile.getName()); + newDestTO = newTemplTO; + } else { + return new CopyCmdAnswer("not implemented yet"); + } - return new CopyCmdAnswer(newDestTO); - } catch (Exception e) { + return new CopyCmdAnswer(newDestTO); + } catch (Exception e) { - final String errMsg = format("Failed to download" - + "due to $2%s", e.getMessage()); - s_logger.error(errMsg, e); - return new CopyCmdAnswer(errMsg); - } + final String errMsg = format("Failed to download" + "due to $2%s", e.getMessage()); + s_logger.error(errMsg, e); + return new CopyCmdAnswer(errMsg); + } } protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, - DataTO destData, NfsTO destImageStore) { - return Answer.createUnsupportedCommandAnswer(cmd); + DataTO destData, NfsTO destImageStore) { + return Answer.createUnsupportedCommandAnswer(cmd); } protected Answer execute(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - DataStoreTO srcDataStore = srcData.getDataStore(); - DataStoreTO destDataStore = destData.getDataStore(); + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + DataStoreTO srcDataStore = srcData.getDataStore(); + DataStoreTO destDataStore = destData.getDataStore(); - if (srcDataStore.getRole() == DataStoreRole.Image - && destDataStore.getRole() == DataStoreRole.ImageCache - ) { + if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache) { - if (!(destDataStore instanceof NfsTO)) { - s_logger.debug("only support nfs as cache storage"); - return Answer.createUnsupportedCommandAnswer(cmd); - } + if (!(destDataStore instanceof NfsTO)) { + s_logger.debug("only support nfs as cache storage"); + return Answer.createUnsupportedCommandAnswer(cmd); + } - if (srcDataStore instanceof S3TO) { - return copyFromS3ToNfs(cmd, srcData, (S3TO)srcDataStore, - destData, (NfsTO)destDataStore); - } else if (srcDataStore instanceof SwiftTO) { - return copyFromSwiftToNfs(cmd, srcData, (SwiftTO)srcDataStore, - destData, (NfsTO)destDataStore); - } else { - return Answer.createUnsupportedCommandAnswer(cmd); - } + if (srcDataStore instanceof S3TO) { + return copyFromS3ToNfs(cmd, srcData, (S3TO) srcDataStore, destData, (NfsTO) destDataStore); + } else if (srcDataStore instanceof SwiftTO) { + return copyFromSwiftToNfs(cmd, srcData, (SwiftTO) srcDataStore, destData, (NfsTO) destDataStore); + } else { + return Answer.createUnsupportedCommandAnswer(cmd); + } - } - return Answer.createUnsupportedCommandAnswer(cmd); + } + return Answer.createUnsupportedCommandAnswer(cmd); } @SuppressWarnings("unchecked") - protected String determineS3TemplateDirectory(final Long accountId, - final Long templateId) { - return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId), - S3Utils.SEPARATOR); + protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) { + return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR); } @SuppressWarnings("unchecked") - private String determineStorageTemplatePath(final String storagePath, - String dataPath) { - return join( - asList(getRootDir(storagePath), dataPath), File.separator); + private String determineS3TemplateNameFromKey(String key){ + return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR); + } + + + @SuppressWarnings("unchecked") + private String determineStorageTemplatePath(final String storagePath, String dataPath) { + return join(asList(getRootDir(storagePath), dataPath), File.separator); } private Answer execute(downloadTemplateFromSwiftToSecondaryStorageCommand cmd) { @@ -383,14 +372,14 @@ SecondaryStorageResource { } } - private Answer execute(DownloadCommand cmd){ + private Answer execute(DownloadCommand cmd) { DataStoreTO dstore = cmd.getDataStore(); - if ( dstore instanceof NfsTO ){ + if (dstore instanceof NfsTO) { return _dlMgr.handleDownloadCommand(this, cmd); - } - else if ( dstore instanceof S3TO ){ - //TODO: how to handle download progress for S3 - S3TO s3 = (S3TO)cmd.getDataStore(); + } else if (dstore instanceof S3TO) { + // TODO: start download job to handle this + // TODO: how to handle download progress for S3 + S3TO s3 = (S3TO) cmd.getDataStore(); String url = cmd.getUrl(); String user = null; String password = null; @@ -412,17 +401,27 @@ SecondaryStorageResource { } final String bucket = s3.getBucketName(); - String key = join(asList(determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId()), urlObj.getFile()), S3Utils.SEPARATOR); + // convention is no / in the end for install path based on S3Utils implementation. + String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); + // template key is + // TEMPLATE_ROOT_DIR/account_id/template_id/template_name + String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR); S3Utils.putObject(s3, in, bucket, key); - return new Answer(cmd, true, format("Uploaded the contents of input stream from %1$s for template id %2$s to S3 bucket %3$s", url, - cmd.getResourceId(), bucket)); - } - else if ( dstore instanceof SwiftTO ){ - //TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle - // source is url, most likely we need to modify our existing swiftUpload python script. + List s3Obj = S3Utils.getDirectory(s3, bucket, path); + if (s3Obj == null || s3Obj.size() == 0) { + return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key); + } else { + return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj.get(0) + .getETag()); + } + } else if (dstore instanceof SwiftTO) { + // TODO: need to move code from + // execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, + // but we need to handle + // source is url, most likely we need to modify our existing + // swiftUpload python script. return new Answer(cmd, false, "Swift is not currently support DownloadCommand"); - } - else{ + } else { return new Answer(cmd, false, "Unsupported image data store: " + dstore); } @@ -456,82 +455,82 @@ SecondaryStorageResource { } private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) { -/* - final S3TO s3 = cmd.getS3(); - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); + /* + final S3TO s3 = cmd.getS3(); + final Long accountId = cmd.getAccountId(); + final Long templateId = cmd.getTemplateId(); - try { + try { - final String templatePath = determineStorageTemplatePath( - cmd.getStoragePath(), accountId, templateId); + final String templatePath = determineStorageTemplatePath( + cmd.getStoragePath(), accountId, templateId); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Found template id " + templateId - + " account id " + accountId + " from directory " - + templatePath + " to upload to S3."); - } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found template id " + templateId + + " account id " + accountId + " from directory " + + templatePath + " to upload to S3."); + } - if (!_storage.isDirectory(templatePath)) { - final String errMsg = format("S3 Sync Failure: Directory %1$s" - + "for template id %2$s does not exist.", templatePath, - templateId); - s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); - } + if (!_storage.isDirectory(templatePath)) { + final String errMsg = format("S3 Sync Failure: Directory %1$s" + + "for template id %2$s does not exist.", templatePath, + templateId); + s_logger.error(errMsg); + return new Answer(cmd, false, errMsg); + } - if (!_storage.isFile(templatePath + "/template.properties")) { - final String errMsg = format("S3 Sync Failure: Template id " - + "%1$s does not exist on the file system.", - templatePath); - s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); - } + if (!_storage.isFile(templatePath + "/template.properties")) { + final String errMsg = format("S3 Sync Failure: Template id " + + "%1$s does not exist on the file system.", + templatePath); + s_logger.error(errMsg); + return new Answer(cmd, false, errMsg); + } - if (s_logger.isDebugEnabled()) { - s_logger.debug(format( - "Pushing template id %1$s from %2$s to S3...", - templateId, templatePath)); - } + if (s_logger.isDebugEnabled()) { + s_logger.debug(format( + "Pushing template id %1$s from %2$s to S3...", + templateId, templatePath)); + } + + final String bucket = s3.getBucketName(); + putDirectory(s3, bucket, _storage.getFile(templatePath), + new FilenameFilter() { + @Override + public boolean accept(final File directory, + final String fileName) { + File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName); + return !fileName.startsWith(".") && !fileToUpload.isDirectory(); + } + }, new ObjectNamingStrategy() { + @Override + public String determineKey(final File file) { + s_logger.debug(String + .format("Determining key using account id %1$s and template id %2$s", + accountId, templateId)); + return join( + asList(determineS3TemplateDirectory( + accountId, templateId), file + .getName()), S3Utils.SEPARATOR); + } + }); + + return new Answer( + cmd, + true, + format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s", + templatePath, templateId, bucket)); + + } catch (Exception e) { + + final String errMsg = format("Failed to upload template id %1$s", + templateId); + s_logger.error(errMsg, e); + return new Answer(cmd, false, errMsg); - final String bucket = s3.getBucketName(); - putDirectory(s3, bucket, _storage.getFile(templatePath), - new FilenameFilter() { - @Override - public boolean accept(final File directory, - final String fileName) { - File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName); - return !fileName.startsWith(".") && !fileToUpload.isDirectory(); } - }, new ObjectNamingStrategy() { - @Override - public String determineKey(final File file) { - s_logger.debug(String - .format("Determining key using account id %1$s and template id %2$s", - accountId, templateId)); - return join( - asList(determineS3TemplateDirectory( - accountId, templateId), file - .getName()), S3Utils.SEPARATOR); - } - }); - - return new Answer( - cmd, - true, - format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s", - templatePath, templateId, bucket)); - - } catch (Exception e) { - - final String errMsg = format("Failed to upload template id %1$s", - templateId); - s_logger.error(errMsg, e); - return new Answer(cmd, false, errMsg); - - } -*/ - return new Answer(cmd, false, "not supported "); + */ + return new Answer(cmd, false, "not supported "); } private Answer execute(DeleteObjectFromSwiftCommand cmd) { @@ -559,53 +558,11 @@ SecondaryStorageResource { - private Answer execute(final DeleteTemplateFromS3Command cmd) { - - final S3TO s3 = cmd.getS3(); - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); - - if (accountId == null || (accountId != null && accountId <= 0)) { - final String errorMessage = "No account id specified for S3 template deletion."; - s_logger.error(errorMessage); - return new Answer(cmd, false, errorMessage); - } - - if (templateId == null || (templateId != null && templateId <= 0)) { - final String errorMessage = "No template id specified for S3 template deletion."; - s_logger.error(errorMessage); - return new Answer(cmd, false, errorMessage); - } - - if (s3 == null) { - final String errorMessge = "No S3 client options provided"; - s_logger.error(errorMessge); - return new Answer(cmd, false, errorMessge); - } - - final String bucket = s3.getBucketName(); - try { - deleteDirectory(s3, bucket, - determineS3TemplateDirectory(templateId, accountId)); - return new Answer(cmd, true, String.format( - "Deleted template %1%s from bucket %2$s.", templateId, - bucket)); - } catch (Exception e) { - final String errorMessage = String - .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s", - templateId, bucket, e.getMessage()); - s_logger.error(errorMessage, e); - return new Answer(cmd, false, errorMessage); - } - - } - String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " - + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() - + " download " + container + " " + rfilename + " -o " + lFullPath); + command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -630,8 +587,8 @@ SecondaryStorageResource { String swiftDownloadContainer(SwiftTO swift, String container, String ldir) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " - + swift.getKey() + " download " + container); + command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -674,11 +631,12 @@ SecondaryStorageResource { Script command = new Script("/bin/bash", s_logger); command.add("-c"); if (size <= SWIFT_MAX_SIZE) { - command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() - + " -K " + swift.getKey() + " upload " + container + " " + file); + command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file); } else { - command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() - + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); + command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + + " " + file); } OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); @@ -705,8 +663,8 @@ SecondaryStorageResource { String[] swiftList(SwiftTO swift, String container, String rFilename) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " - + swift.getKey() + " list " + container + " " + rFilename); + command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + + ":" + swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result == null && parser.getLines() != null) { @@ -727,9 +685,8 @@ SecondaryStorageResource { String swiftDelete(SwiftTO swift, String container, String object) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " - + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() - + " delete " + container + " " + object); + command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() + + ":" + swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -750,8 +707,7 @@ SecondaryStorageResource { return null; } - - public Answer execute(DeleteSnapshotsDirCommand cmd){ + public Answer execute(DeleteSnapshotsDirCommand cmd) { String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); Long volumeId = cmd.getVolumeId(); @@ -781,34 +737,24 @@ SecondaryStorageResource { try { - executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), - new Callable() { + executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable() { @Override public Void call() throws Exception { - final String directoryName = determineSnapshotLocalDirectory( - secondaryStorageUrl, accountId, volumeId); + final String directoryName = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId); String result = createLocalDir(directoryName); if (result != null) { - throw new InternalErrorException( - format("Failed to create directory %1$s during S3 snapshot download.", - directoryName)); + throw new InternalErrorException(format("Failed to create directory %1$s during S3 snapshot download.", directoryName)); } - final String snapshotFileName = determineSnapshotBackupFilename(cmd - .getSnapshotUuid()); - final String key = determineSnapshotS3Key( - accountId, volumeId, snapshotFileName); - final File targetFile = S3Utils.getFile(s3, - s3.getBucketName(), key, - _storage.getFile(directoryName), - new FileNamingStrategy() { + final String snapshotFileName = determineSnapshotBackupFilename(cmd.getSnapshotUuid()); + final String key = determineSnapshotS3Key(accountId, volumeId, snapshotFileName); + final File targetFile = S3Utils.getFile(s3, s3.getBucketName(), key, _storage.getFile(directoryName), new FileNamingStrategy() { @Override - public String determineFileName( - String key) { + public String determineFileName(String key) { return snapshotFileName; } @@ -816,19 +762,11 @@ SecondaryStorageResource { if (cmd.getParent() != null) { - final String parentPath = join( - File.pathSeparator, directoryName, - determineSnapshotBackupFilename(cmd - .getParent())); - result = setVhdParent( - targetFile.getAbsolutePath(), - parentPath); + final String parentPath = join(File.pathSeparator, directoryName, determineSnapshotBackupFilename(cmd.getParent())); + result = setVhdParent(targetFile.getAbsolutePath(), parentPath); if (result != null) { - throw new InternalErrorException( - format("Failed to set the parent for backup %1$s to %2$s due to %3$s.", - targetFile - .getAbsolutePath(), - parentPath, result)); + throw new InternalErrorException(format("Failed to set the parent for backup %1$s to %2$s due to %3$s.", + targetFile.getAbsolutePath(), parentPath, result)); } } @@ -839,44 +777,37 @@ SecondaryStorageResource { }); - return new Answer( - cmd, - true, - format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.", - volumeId, accountId, secondaryStorageUrl)); + return new Answer(cmd, true, format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.", volumeId, accountId, + secondaryStorageUrl)); } catch (Exception e) { - final String errMsg = format( - "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s", - volumeId, accountId, secondaryStorageUrl, e.getMessage()); + final String errMsg = format("Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s", volumeId, + accountId, secondaryStorageUrl, e.getMessage()); s_logger.error(errMsg); return new Answer(cmd, false, errMsg); } } - private String determineSnapshotS3Directory(final Long accountId, - final Long volumeId) { + + + + private String determineSnapshotS3Directory(final Long accountId, final Long volumeId) { return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId); } - private String determineSnapshotS3Key(final Long accountId, - final Long volumeId, final String snapshotFileName) { + private String determineSnapshotS3Key(final Long accountId, final Long volumeId, final String snapshotFileName) { - final String directoryName = determineSnapshotS3Directory(accountId, - volumeId); + final String directoryName = determineSnapshotS3Directory(accountId, volumeId); return join(S3Utils.SEPARATOR, directoryName, snapshotFileName); } - private String determineSnapshotLocalDirectory( - final String secondaryStorageUrl, final Long accountId, - final Long volumeId) { - return join(File.pathSeparator, getRootDir(secondaryStorageUrl), - SNAPSHOT_ROOT_DIR, accountId, volumeId); + private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, final Long volumeId) { + return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId); } - public Answer execute(downloadSnapshotFromSwiftCommand cmd){ + public Answer execute(downloadSnapshotFromSwiftCommand cmd) { SwiftTO swift = cmd.getSwift(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); @@ -889,13 +820,13 @@ SecondaryStorageResource { String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId); String result = createLocalDir(lPath); - if ( result != null ) { + if (result != null) { errMsg = "downloadSnapshotFromSwiftCommand failed due to Create local path failed"; s_logger.warn(errMsg); throw new InternalErrorException(errMsg); } String lFilename = rFilename; - if ( rFilename.startsWith("VHD-") ) { + if (rFilename.startsWith("VHD-")) { lFilename = rFilename.replace("VHD-", "") + ".vhd"; } String lFullPath = lPath + "/" + lFilename; @@ -944,38 +875,36 @@ SecondaryStorageResource { InputStream is = null; byte[] buffer = new byte[8192]; int read = 0; - if(s_logger.isDebugEnabled()){ - s_logger.debug("parent path " +parent+ " relative template path " +relativeTemplatePath ); + if (s_logger.isDebugEnabled()) { + s_logger.debug("parent path " + parent + " relative template path " + relativeTemplatePath); } - try { digest = MessageDigest.getInstance("MD5"); is = new FileInputStream(f); - while( (read = is.read(buffer)) > 0) { + while ((read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); checksum = bigInt.toString(16); - if(s_logger.isDebugEnabled()){ - s_logger.debug("Successfully calculated checksum for file " +absoluteTemplatePath+ " - " +checksum ); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully calculated checksum for file " + absoluteTemplatePath + " - " + checksum); } - }catch(IOException e) { + } catch (IOException e) { String logMsg = "Unable to process file for MD5 - " + absoluteTemplatePath; s_logger.error(logMsg); return new Answer(cmd, false, checksum); - }catch (NoSuchAlgorithmException e) { + } catch (NoSuchAlgorithmException e) { return new Answer(cmd, false, checksum); - } - finally { + } finally { try { - if(is != null) + if (is != null) is.close(); } catch (IOException e) { - if(s_logger.isDebugEnabled()){ - s_logger.debug("Could not close the file " +absoluteTemplatePath); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Could not close the file " + absoluteTemplatePath); } return new Answer(cmd, false, checksum); } @@ -1018,11 +947,11 @@ SecondaryStorageResource { } private Answer execute(SecStorageSetupCommand cmd) { - if (!_inSystemVM){ + if (!_inSystemVM) { return new Answer(cmd, true, null); } DataStoreTO dStore = cmd.getDataStore(); - if (dStore instanceof NfsTO ){ + if (dStore instanceof NfsTO) { String secUrl = cmd.getSecUrl(); try { URI uri = new URI(secUrl); @@ -1047,20 +976,17 @@ SecondaryStorageResource { return new Answer(cmd, false, msg); } - } - else{ - // TODO: what do we need to setup for S3/Swift, maybe need to mount to some cache storage + } else { + // TODO: what do we need to setup for S3/Swift, maybe need to mount + // to some cache storage return new Answer(cmd, true, null); } } - private String deleteSnapshotBackupFromLocalFileSystem( - final String secondaryStorageUrl, final Long accountId, - final Long volumeId, final String name, final Boolean deleteAllFlag) { + private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId, + final String name, final Boolean deleteAllFlag) { - final String lPath = determineSnapshotLocalDirectory( - secondaryStorageUrl, accountId, volumeId) - + File.pathSeparator + final String lPath = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId) + File.pathSeparator + (deleteAllFlag ? "*" : "*" + name + "*"); final String result = deleteLocalFile(lPath); @@ -1073,58 +999,40 @@ SecondaryStorageResource { } - private String deleteSnapshotBackupfromS3(final S3TO s3, - final String secondaryStorageUrl, final Long accountId, - final Long volumeId, final String name, final Boolean deleteAllFlag) { + private String deleteSnapshotBackupfromS3(final S3TO s3, final String secondaryStorageUrl, final Long accountId, final Long volumeId, + final String name, final Boolean deleteAllFlag) { try { final String bucket = s3.getBucketName(); - final String result = executeWithNoWaitLock( - determineSnapshotLockId(accountId, volumeId), - new Callable() { + final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable() { - @Override - public String call() throws Exception { + @Override + public String call() throws Exception { - final String innerResult = deleteSnapshotBackupFromLocalFileSystem( - secondaryStorageUrl, accountId, volumeId, - name, deleteAllFlag); - if (innerResult != null) { - return innerResult; - } + final String innerResult = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, deleteAllFlag); + if (innerResult != null) { + return innerResult; + } - if (deleteAllFlag) { - S3Utils.deleteDirectory( - s3, - bucket, - determineSnapshotS3Directory(accountId, - volumeId)); - } else { - S3Utils.deleteObject( - s3, - bucket, - determineSnapshotS3Key( - accountId, - volumeId, - determineSnapshotBackupFilename(name))); - } + if (deleteAllFlag) { + S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId)); + } else { + S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name))); + } - return null; + return null; - } + } - }); + }); return result; } catch (Exception e) { - s_logger.error( - String.format( - "Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", - accountId, volumeId), e); + s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", accountId, volumeId), e); return e.getMessage(); } @@ -1135,8 +1043,7 @@ SecondaryStorageResource { return snapshotUuid + ".vhd"; } - private String determineSnapshotLockId(final Long accountId, - final Long volumeId) { + private String determineSnapshotLockId(final Long accountId, final Long volumeId) { return join("_", "SNAPSHOT", accountId, volumeId); } @@ -1146,30 +1053,26 @@ SecondaryStorageResource { Long volumeId = cmd.getVolumeId(); String name = cmd.getSnapshotUuid(); DataStoreTO dstore = cmd.getDataStore(); - if ( dstore instanceof NfsTO ){ - final String result = deleteSnapshotBackupFromLocalFileSystem( - secondaryStorageUrl, accountId, volumeId, name, - cmd.isAll()); + if (dstore instanceof NfsTO) { + final String result = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, cmd.isAll()); if (result != null) { s_logger.warn(result); return new Answer(cmd, false, result); } - } else if (dstore instanceof S3TO ){ - final String result = deleteSnapshotBackupfromS3((S3TO)dstore, - secondaryStorageUrl, accountId, volumeId, name, - cmd.isAll()); + } else if (dstore instanceof S3TO) { + final String result = deleteSnapshotBackupfromS3((S3TO) dstore, secondaryStorageUrl, accountId, volumeId, name, cmd.isAll()); if (result != null) { s_logger.warn(result); return new Answer(cmd, false, result); } - } else if (dstore instanceof SwiftTO ){ + } else if (dstore instanceof SwiftTO) { String filename; if (cmd.isAll()) { filename = ""; } else { filename = name; } - String result = swiftDelete((SwiftTO)dstore, "V-" + volumeId.toString(), filename); + String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId.toString(), filename); if (result != null) { String errMsg = "failed to delete snapshot " + filename + " , err=" + result; s_logger.warn(errMsg); @@ -1187,8 +1090,8 @@ SecondaryStorageResource { return null; } Map tmpltInfos = new HashMap(); - for( String container : containers) { - if ( container.startsWith("T-")) { + for (String container : containers) { + if (container.startsWith("T-")) { String ldir = _tmpltDir + "/" + UUID.randomUUID().toString(); createLocalDir(ldir); String lFullPath = ldir + "/" + _tmpltpp; @@ -1214,22 +1117,51 @@ SecondaryStorageResource { } + Map s3ListTemplate(S3TO s3) { + String bucket = s3.getBucketName(); + // List the objects in the source directory on S3 + final List objectSummaries = S3Utils.getDirectory(s3, bucket, this.TEMPLATE_ROOT_DIR); + if ( objectSummaries == null ) + return null; + Map tmpltInfos = new HashMap(); + for (S3ObjectSummary objectSummary : objectSummaries){ + String key = objectSummary.getKey(); + String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); + String uniqueName = this.determineS3TemplateNameFromKey(key); + //TODO: isPublic value, where to get? + TemplateProp tInfo = new TemplateProp(uniqueName, installPath, objectSummary.getSize(), objectSummary.getSize(), true, false); + tmpltInfos.put(uniqueName, tInfo); + } + return tmpltInfos; + + } + private Answer execute(ListTemplateCommand cmd) { - if (!_inSystemVM){ + if (!_inSystemVM) { return new Answer(cmd, true, null); } - if (cmd.getSwift() != null) { - Map templateInfos = swiftListTemplate(cmd.getSwift()); - return new ListTemplateAnswer(cmd.getSwift().toString(), templateInfos); - } else { - String root = getRootDir(cmd.getSecUrl()); + + DataStoreTO store = cmd.getDataStore(); + if (store instanceof NfsTO) { + NfsTO nfs = (NfsTO)store; + String root = getRootDir(nfs.getUrl()); Map templateInfos = _dlMgr.gatherTemplateInfo(root); - return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); + return new ListTemplateAnswer(nfs.getUrl(), templateInfos); + } else if (store instanceof SwiftTO) { + SwiftTO swift = (SwiftTO) store; + Map templateInfos = swiftListTemplate(swift); + return new ListTemplateAnswer(swift.toString(), templateInfos); + } else if (store instanceof S3TO) { + S3TO s3 = (S3TO) store; + Map templateInfos = s3ListTemplate(s3); + return new ListTemplateAnswer(s3.getBucketName(), templateInfos); + } else { + return new Answer(cmd, false, "Unsupported image data store: " + store); } } private Answer execute(ListVolumeCommand cmd) { - if (!_inSystemVM){ + if (!_inSystemVM) { return new Answer(cmd, true, null); } @@ -1240,12 +1172,12 @@ SecondaryStorageResource { } private Answer execute(SecStorageVMSetupCommand cmd) { - if (!_inSystemVM){ + if (!_inSystemVM) { return new Answer(cmd, true, null); } boolean success = true; StringBuilder result = new StringBuilder(); - for (String cidr: cmd.getAllowedInternalSites()) { + for (String cidr : cmd.getAllowedInternalSites()) { if (nfsIps.contains(cidr)) { /* * if the internal download ip is the same with secondary storage ip, adding internal sites will flush @@ -1333,7 +1265,7 @@ SecondaryStorageResource { String result = command.execute(); if (result != null) { - s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result ); + s_logger.warn("Error in allowing outgoing to " + destCidr + ", err=" + result); return "Error in allowing outgoing to " + destCidr + ", err=" + result; } @@ -1343,13 +1275,13 @@ SecondaryStorageResource { } private Answer execute(SecStorageFirewallCfgCommand cmd) { - if (!_inSystemVM){ + if (!_inSystemVM) { return new Answer(cmd, true, null); } List ipList = new ArrayList(); - for (PortConfig pCfg:cmd.getPortConfigs()){ + for (PortConfig pCfg : cmd.getPortConfigs()) { if (pCfg.isAdd()) { ipList.add(pCfg.getSourceIp()); } @@ -1357,7 +1289,7 @@ SecondaryStorageResource { boolean success = true; String result; result = configureIpFirewall(ipList, cmd.getIsAppendAIp()); - if (result !=null) + if (result != null) success = false; return new Answer(cmd, success, result); @@ -1370,15 +1302,16 @@ SecondaryStorageResource { if (usedSize == -1 || totalSize == -1) { return new GetStorageStatsAnswer(cmd, "Unable to get storage stats"); } else { - return new GetStorageStatsAnswer(cmd, totalSize, usedSize) ; + return new GetStorageStatsAnswer(cmd, totalSize, usedSize); } } protected Answer execute(final DeleteTemplateCommand cmd) { DataStoreTO dstore = cmd.getDataStore(); if (dstore instanceof NfsTO) { + NfsTO nfs = (NfsTO)dstore; String relativeTemplatePath = cmd.getTemplatePath(); - String parent = getRootDir(cmd); + String parent = getRootDir(nfs.getUrl()); if (relativeTemplatePath.startsWith(File.separator)) { relativeTemplatePath = relativeTemplatePath.substring(1); @@ -1420,40 +1353,21 @@ SecondaryStorageResource { return new Answer(cmd, false, details); } return new Answer(cmd, true, null); - } else if (dstore instanceof S3TO ){ - final S3TO s3 = (S3TO)dstore; - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); - - if (accountId == null || (accountId != null && accountId <= 0)) { - final String errorMessage = "No account id specified for S3 template deletion."; - s_logger.error(errorMessage); - return new Answer(cmd, false, errorMessage); - } - - if (templateId == null || (templateId != null && templateId <= 0)) { - final String errorMessage = "No template id specified for S3 template deletion."; - s_logger.error(errorMessage); - return new Answer(cmd, false, errorMessage); - } - - + } else if (dstore instanceof S3TO) { + final S3TO s3 = (S3TO) dstore; + final String path = cmd.getTemplatePath(); final String bucket = s3.getBucketName(); try { - S3Utils.deleteDirectory(s3, bucket, - determineS3TemplateDirectory(templateId, accountId)); - return new Answer(cmd, true, String.format( - "Deleted template %1%s from bucket %2$s.", templateId, - bucket)); + S3Utils.deleteDirectory(s3, bucket, path); + return new Answer(cmd, true, String.format("Deleted template %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String - .format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s", - templateId, bucket, e.getMessage()); + final String errorMessage = String.format("Failed to delete templaet %1$s from bucket %2$s due to the following error: %3$s", + path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } - } else if (dstore instanceof SwiftTO){ - SwiftTO swift = (SwiftTO)dstore; + } else if (dstore instanceof SwiftTO) { + SwiftTO swift = (SwiftTO) dstore; String container = "T-" + cmd.getTemplateId(); String object = ""; @@ -1470,7 +1384,7 @@ SecondaryStorageResource { s_logger.warn(errMsg, e); return new Answer(cmd, false, errMsg); } - } else{ + } else { return new Answer(cmd, false, "Unsupported image data store: " + dstore); } } @@ -1505,8 +1419,7 @@ SecondaryStorageResource { found = true; } if (!f.delete()) { - return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " - + relativeVolumePath); + return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath); } } if (!found) { @@ -1515,8 +1428,7 @@ SecondaryStorageResource { } } if (!tmpltParent.delete()) { - details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " - + relativeVolumePath; + details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + relativeVolumePath; s_logger.debug(details); return new Answer(cmd, false, details); } @@ -1528,7 +1440,8 @@ SecondaryStorageResource { if (!parent.endsWith(File.separator)) { parent += File.separator; } - String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + cmd.getVolumeId(); + String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator + + cmd.getVolumeId(); File ssParent = new File(absoluteSnapsthotDir); if (ssParent.exists() && ssParent.isDirectory()) { File[] files = ssParent.listFiles(); @@ -1551,7 +1464,6 @@ SecondaryStorageResource { return new Answer(cmd, true, null); } - synchronized public String getRootDir(String secUrl) { try { URI uri = new URI(secUrl); @@ -1571,9 +1483,8 @@ SecondaryStorageResource { } } - @Override - public String getRootDir(ssCommand cmd){ + public String getRootDir(ssCommand cmd) { return getRootDir(cmd.getSecUrl()); } @@ -1602,13 +1513,12 @@ SecondaryStorageResource { assert (false) : "Well, I have no idea what this is: " + size; } - return (long)(Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier); + return (long) (Double.parseDouble(size.substring(0, size.length() - 1)) * multiplier); } - @Override public Type getType() { - if(SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) + if (SecondaryStorageVm.Role.templateProcessor.toString().equals(_role)) return Host.Type.SecondaryStorage; return Host.Type.SecondaryStorageCmdExecutor; @@ -1621,9 +1531,9 @@ SecondaryStorageResource { @Override public boolean configure(String name, Map params) throws ConfigurationException { - _eth1ip = (String)params.get("eth1ip"); - _eth1mask = (String)params.get("eth1mask"); - if (_eth1ip != null) { //can only happen inside service vm + _eth1ip = (String) params.get("eth1ip"); + _eth1mask = (String) params.get("eth1mask"); + if (_eth1ip != null) { // can only happen inside service vm params.put("private.network.device", "eth1"); } else { s_logger.warn("Wait, what's going on? eth1ip is null!!"); @@ -1644,19 +1554,19 @@ SecondaryStorageResource { super.configure(name, params); _params = params; - String value = (String)params.get("scripts.timeout"); + String value = (String) params.get("scripts.timeout"); _timeout = NumbersUtil.parseInt(value, 1440) * 1000; - _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey); + _storage = (StorageLayer) params.get(StorageLayer.InstanceConfigKey); if (_storage == null) { - value = (String)params.get(StorageLayer.ClassConfigKey); + value = (String) params.get(StorageLayer.ClassConfigKey); if (value == null) { value = "com.cloud.storage.JavaStorageLayer"; } try { Class clazz = Class.forName(value); - _storage = (StorageLayer)clazz.newInstance(); + _storage = (StorageLayer) clazz.newInstance(); _storage.configure("StorageLayer", params); } catch (ClassNotFoundException e) { throw new ConfigurationException("Unable to find class " + value); @@ -1682,29 +1592,28 @@ SecondaryStorageResource { s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr); } - _role = (String)params.get("role"); - if(_role == null) + _role = (String) params.get("role"); + if (_role == null) _role = SecondaryStorageVm.Role.templateProcessor.toString(); s_logger.info("Secondary storage runs in role " + _role); - _guid = (String)params.get("guid"); + _guid = (String) params.get("guid"); if (_guid == null) { throw new ConfigurationException("Unable to find the guid"); } - _dc = (String)params.get("zone"); + _dc = (String) params.get("zone"); if (_dc == null) { throw new ConfigurationException("Unable to find the zone"); } - _pod = (String)params.get("pod"); + _pod = (String) params.get("pod"); - _instance = (String)params.get("instance"); + _instance = (String) params.get("instance"); - - String inSystemVM = (String)params.get("secondary.storage.vm"); + String inSystemVM = (String) params.get("secondary.storage.vm"); if (inSystemVM == null || "true".equalsIgnoreCase(inSystemVM)) { _inSystemVM = true; - _localgw = (String)params.get("localgw"); + _localgw = (String) params.get("localgw"); if (_localgw != null) { // can only happen inside service vm String mgmtHost = (String) params.get("host"); addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost); @@ -1747,14 +1656,14 @@ SecondaryStorageResource { command.add("if [ -f /etc/init.d/ssh ]; then service ssh restart; else service sshd restart; fi "); String result = command.execute(); if (result != null) { - s_logger.warn("Error in starting sshd service err=" + result ); + s_logger.warn("Error in starting sshd service err=" + result); } command = new Script("/bin/bash", s_logger); command.add("-c"); command.add("iptables -I INPUT -i eth1 -p tcp -m state --state NEW -m tcp --dport 3922 -j ACCEPT"); result = command.execute(); if (result != null) { - s_logger.warn("Error in opening up ssh port err=" + result ); + s_logger.warn("Error in opening up ssh port err=" + result); } } @@ -1764,7 +1673,7 @@ SecondaryStorageResource { s_logger.debug("addRouteToInternalIp: destIp is null"); return; } - if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)){ + if (!NetUtils.isValidIp(destIpOrCidr) && !NetUtils.isValidCIDR(destIpOrCidr)) { s_logger.warn(" destIp is not a valid ip address or cidr destIp=" + destIpOrCidr); return; } @@ -1773,7 +1682,8 @@ SecondaryStorageResource { if (eth1ip != null && eth1mask != null) { inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask); } else { - s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + ", _eth1mask=" + eth1mask); + s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr + + ", _eth1mask=" + eth1mask); } } else { inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask)); @@ -1791,7 +1701,7 @@ SecondaryStorageResource { command.add("ip route add " + destIpOrCidr + " via " + localgw); String result = command.execute(); if (result != null) { - s_logger.warn("Error in configuring route to internal ip err=" + result ); + s_logger.warn("Error in configuring route to internal ip err=" + result); } else { s_logger.debug("addRouteToInternalIp: added route to internal ip=" + destIpOrCidr + " via " + localgw); } @@ -1833,16 +1743,16 @@ SecondaryStorageResource { return result; } - private String configureIpFirewall(List ipList, boolean isAppend){ + private String configureIpFirewall(List ipList, boolean isAppend) { Script command = new Script(_configIpFirewallScr); command.add(String.valueOf(isAppend)); - for (String ip : ipList){ + for (String ip : ipList) { command.add(ip); } String result = command.execute(); if (result != null) { - s_logger.warn("Unable to configure firewall for command : " +command); + s_logger.warn("Unable to configure firewall for command : " + command); } return result; } @@ -1865,8 +1775,8 @@ SecondaryStorageResource { ZfsPathParser parser = new ZfsPathParser(root); script.execute(parser); res.addAll(parser.getPaths()); - for( String s : res ) { - if ( s.contains(root)) { + for (String s : res) { + if (s.contains(root)) { return root; } } @@ -1874,7 +1784,7 @@ SecondaryStorageResource { Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger); command.add("-t", "nfs"); if (_inSystemVM) { - //Fedora Core 12 errors out with any -o option executed from java + // Fedora Core 12 errors out with any -o option executed from java command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0"); } command.add(nfsPath); @@ -1888,7 +1798,8 @@ SecondaryStorageResource { return null; } - // XXX: Adding the check for creation of snapshots dir here. Might have to move it somewhere more logical later. + // XXX: Adding the check for creation of snapshots dir here. Might have + // to move it somewhere more logical later. if (!checkForSnapshotsDir(root)) { return null; } @@ -1916,7 +1827,7 @@ SecondaryStorageResource { final StartupSecondaryStorageCommand cmd = new StartupSecondaryStorageCommand(); fillNetworkInformation(cmd); - if(_publicIp != null) + if (_publicIp != null) cmd.setPublicIpAddress(_publicIp); Script command = new Script("/bin/bash", s_logger); @@ -1927,7 +1838,7 @@ SecondaryStorageResource { s_logger.warn("Error in linking err=" + result); return null; } - return new StartupCommand[] {cmd}; + return new StartupCommand[] { cmd }; } protected boolean checkForSnapshotsDir(String mountPoint) { @@ -1958,7 +1869,7 @@ SecondaryStorageResource { } if (dirExists) { - s_logger.info(dirName + " directory created/exists on Secondary Storage."); + s_logger.info(dirName + " directory created/exists on Secondary Storage."); } else { s_logger.info(dirName + " directory does not exist on Secondary Storage."); } @@ -1971,33 +1882,33 @@ SecondaryStorageResource { return "./scripts/storage/secondary"; } - @Override - public void setName(String name) { - // TODO Auto-generated method stub + @Override + public void setName(String name) { + // TODO Auto-generated method stub - } + } - @Override - public void setConfigParams(Map params) { - // TODO Auto-generated method stub + @Override + public void setConfigParams(Map params) { + // TODO Auto-generated method stub - } + } - @Override - public Map getConfigParams() { - // TODO Auto-generated method stub - return null; - } + @Override + public Map getConfigParams() { + // TODO Auto-generated method stub + return null; + } - @Override - public int getRunLevel() { - // TODO Auto-generated method stub - return 0; - } + @Override + public int getRunLevel() { + // TODO Auto-generated method stub + return 0; + } - @Override - public void setRunLevel(int level) { - // TODO Auto-generated method stub + @Override + public void setRunLevel(int level) { + // TODO Auto-generated method stub - } + } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 708bda75347..cc9ad437155 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -414,7 +414,7 @@ public class TemplateServiceImpl implements TemplateService { private Map listTemplate(DataStore ssStore) { - ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getUri()); + ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO()); EndPoint ep = _epSelector.select(ssStore); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 0ef735c8292..d3f6916c6a2 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -292,7 +292,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); EndPoint ep = _epSelector.select(templateObj); Answer answer = ep.sendMessage(cmd); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 740dcdcf930..4844167753c 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -249,7 +249,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); EndPoint ep = _epSelector.select(templateObj); Answer answer = ep.sendMessage(cmd); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 00ed2c5a411..4fc69484f0f 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -243,7 +243,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId()); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); EndPoint ep = _epSelector.select(templateObj); Answer answer = ep.sendMessage(cmd); diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index fc62a563aba..73dfa8052f3 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -93,7 +93,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver CreateCmdResult result = null; CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult()) { - result = new CreateCmdResult(volAnswer.getPath(), volAnswer.getSize()); + result = new CreateCmdResult(volAnswer.getPath(), volAnswer); } else { result = new CreateCmdResult("", null); result.setResult(volAnswer.getDetails()); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 37fb3769156..60ccc2be6fc 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1245,7 +1245,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (installPath != null) { EndPoint ep = _epSelector.select(store); - Command cmd = new DeleteTemplateCommand(store.getTO(), store.getUri(), destroyedTemplateStoreVO.getInstallPath(), + Command cmd = new DeleteTemplateCommand(store.getTO(), destroyedTemplateStoreVO.getInstallPath(), destroyedTemplate.getId(), destroyedTemplate.getAccountId()); Answer answer = ep.sendMessage(cmd); diff --git a/server/src/com/cloud/storage/s3/S3Manager.java b/server/src/com/cloud/storage/s3/S3Manager.java index 14da1da3577..058c5caf32c 100644 --- a/server/src/com/cloud/storage/s3/S3Manager.java +++ b/server/src/com/cloud/storage/s3/S3Manager.java @@ -49,7 +49,7 @@ public interface S3Manager extends Manager { boolean isTemplateInstalled(Long templateId); - void deleteTemplate(final Long accountId, final Long templateId); + //void deleteTemplate(final Long accountId, final Long templateId); String downloadTemplateFromS3ToSecondaryStorage(final long dcId, final long templateId, final int primaryStorageDownloadWait); diff --git a/server/src/com/cloud/storage/s3/S3ManagerImpl.java b/server/src/com/cloud/storage/s3/S3ManagerImpl.java index 06106db432c..cf236b8b9d3 100644 --- a/server/src/com/cloud/storage/s3/S3ManagerImpl.java +++ b/server/src/com/cloud/storage/s3/S3ManagerImpl.java @@ -41,7 +41,6 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; -import javax.annotation.PostConstruct; import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -54,7 +53,6 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteTemplateFromS3Command; import com.cloud.agent.api.DownloadTemplateFromS3ToSecondaryStorageCommand; import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand; import com.cloud.agent.api.to.S3TO; @@ -282,70 +280,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { + "been implemented"); } - @Override - public void deleteTemplate(final Long templateId, final Long accountId) { - final S3TO s3 = getS3TO(); - - if (s3 == null) { - final String errorMessage = "Delete Template Failed: No S3 configuration defined."; - LOGGER.error(errorMessage); - throw new CloudRuntimeException(errorMessage); - } - - final VMTemplateS3VO vmTemplateS3VO = vmTemplateS3Dao - .findOneByS3Template(s3.getId(), templateId); - if (vmTemplateS3VO == null) { - final String errorMessage = format( - "Delete Template Failed: Unable to find Template %1$s in S3.", - templateId); - LOGGER.error(errorMessage); - throw new CloudRuntimeException(errorMessage); - } - - try { - - executeWithNoWaitLock(determineLockId(accountId, templateId), - new Callable() { - - @Override - public Void call() throws Exception { - - final Answer answer = agentManager.sendToSSVM(null, - new DeleteTemplateFromS3Command(s3, - accountId, templateId)); - if (answer == null || !answer.getResult()) { - final String errorMessage = format( - "Delete Template Failed: Unable to delete template id %1$s from S3 due to following error: %2$s", - templateId, - ((answer == null) ? "answer is null" - : answer.getDetails())); - LOGGER.error(errorMessage); - throw new CloudRuntimeException(errorMessage); - } - - vmTemplateS3Dao.remove(vmTemplateS3VO.getId()); - LOGGER.debug(format( - "Deleted template %1$s from S3.", - templateId)); - - return null; - - } - - }); - - } catch (Exception e) { - - final String errorMessage = format( - "Delete Template Failed: Unable to delete template id %1$s from S3 due to the following error: %2$s.", - templateId, e.getMessage()); - LOGGER.error(errorMessage); - throw new CloudRuntimeException(errorMessage, e); - - } - - } @SuppressWarnings("unchecked") @Override diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index 423ea7138a9..a0eb7d334ea 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -54,6 +54,7 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.Bucket; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.utils.exception.CloudRuntimeException; @@ -155,6 +156,22 @@ public final class S3Utils { } + // Note that whenever S3Object is returned, client code needs to close the internal stream to avoid resource leak. + public static S3Object getObject(final ClientOptions clientOptions, + final String bucketName, final String key) { + + assert clientOptions != null; + assert !isBlank(bucketName); + assert !isBlank(key); + + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(format("Get S3 object %1$s in " + + "bucket %2$s", key, bucketName)); + } + + return acquireClient(clientOptions).getObject(bucketName, key); + + } @SuppressWarnings("unchecked") public static File getFile(final ClientOptions clientOptions, @@ -243,6 +260,18 @@ public final class S3Utils { } + public static List getDirectory(final ClientOptions clientOptions, + final String bucketName, final String sourcePath){ + assert clientOptions != null; + assert isNotBlank(bucketName); + assert isNotBlank(sourcePath); + + final AmazonS3 connection = acquireClient(clientOptions); + + // List the objects in the source directory on S3 + return listDirectory(bucketName, sourcePath, connection); + } + private static List listDirectory(final String bucketName, final String directory, final AmazonS3 client) { From 66f510bc386a170cec98cae53aecf750489342c0 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 26 Apr 2013 14:02:42 -0700 Subject: [PATCH 067/303] Fix build error due to ListTemplateCommand change. --- .../cloud/agent/manager/MockStorageManagerImpl.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index ae7cf298e97..d8a3e510521 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -56,6 +56,7 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.simulator.MockHost; @@ -82,6 +83,7 @@ import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine.State; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.to.NfsTO; import javax.ejb.Local; import javax.inject.Inject; @@ -468,18 +470,23 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa @Override public Answer ListTemplates(ListTemplateCommand cmd) { + DataStoreTO store = cmd.getDataStore(); + if ( !(store instanceof NfsTO )){ + return new Answer(cmd, false, "Unsupported image data store: " + store); + } Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); MockSecStorageVO storage = null; + String nfsUrl = ((NfsTO)cmd.getDataStore()).getUrl(); try { txn.start(); - storage = _mockSecStorageDao.findByUrl(cmd.getSecUrl()); + storage = _mockSecStorageDao.findByUrl(nfsUrl); if (storage == null) { return new Answer(cmd, false, "Failed to get secondary storage"); } txn.commit(); } catch (Exception ex) { txn.rollback(); - throw new CloudRuntimeException("Error when finding sec storage " + cmd.getSecUrl(), ex); + throw new CloudRuntimeException("Error when finding sec storage " + nfsUrl, ex); } finally { txn.close(); txn = Transaction.open(Transaction.CLOUD_DB); @@ -498,7 +505,7 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa .replaceAll(storage.getMountPoint(), ""), template.getSize(), template.getSize(), true, false)); } txn.commit(); - return new ListTemplateAnswer(cmd.getSecUrl(), templateInfos); + return new ListTemplateAnswer(nfsUrl, templateInfos); } catch (Exception ex) { txn.rollback(); throw new CloudRuntimeException("Error when finding template on sec storage " + storage.getId(), ex); From 471ad5108086d849b74f6f4801456e9d244f2ebf Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 26 Apr 2013 16:34:23 -0700 Subject: [PATCH 068/303] Handle Volume type in DownloadCommand. --- .../agent/api/storage/DownloadCommand.java | 18 +- .../DownloadSystemTemplateCommand.java | 2 - .../resource/NfsSecondaryStorageResource.java | 23 +- .../cloud/agent/transport/RequestTest.java | 2 +- .../storage/download/DownloadMonitorImpl.java | 226 +----------------- 5 files changed, 34 insertions(+), 237 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/api/src/com/cloud/agent/api/storage/DownloadCommand.java index 81577b5dec6..8293b445cd7 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadCommand.java @@ -21,6 +21,7 @@ import java.net.URI; import org.apache.cloudstack.api.InternalIdentity; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; @@ -125,36 +126,41 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal this.resourceType = that.resourceType; } - public DownloadCommand(DataStoreTO store, String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { + public DownloadCommand(DataStoreTO store, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { super(template.getUniqueName(), template.getUrl(), template.getFormat(), template.getAccountId()); this._store = store; this.hvm = template.isRequiresHvm(); this.checksum = template.getChecksum(); this.id = template.getId(); this.description = template.getDisplayText(); - this.setSecUrl(secUrl); + if (store instanceof NfsTO) { + this.setSecUrl(((NfsTO) store).getUrl()); + } this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceId = template.getId(); } - public DownloadCommand(String secUrl, Volume volume, Long maxDownloadSizeInBytes, String checkSum, String url, ImageFormat format) { + public DownloadCommand(DataStoreTO store, Volume volume, Long maxDownloadSizeInBytes, String checkSum, String url, ImageFormat format) { super(volume.getName(), url, format, volume.getAccountId()); //this.hvm = volume.isRequiresHvm(); this.checksum = checkSum; this.id = volume.getId(); - this.setSecUrl(secUrl); + this._store = store; this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceType = ResourceType.VOLUME; + this.resourceId = volume.getId(); } - public DownloadCommand(DataStoreTO store, String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { + public DownloadCommand(DataStoreTO store, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { super(template.getUniqueName(), url, template.getFormat(), template.getAccountId()); this._store = store; this.hvm = template.isRequiresHvm(); this.checksum = template.getChecksum(); this.id = template.getId(); this.description = template.getDisplayText(); - this.setSecUrl(secUrl); + if (store instanceof NfsTO) { + this.setSecUrl(((NfsTO) store).getUrl()); + } this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; auth = new PasswordAuth(user, passwd); } diff --git a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java index 6bdd9bcdfbd..13678e7085f 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.agent.api.storage; -import java.net.URI; - import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.to.DataStoreTO; diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 0abe1499977..5218933f32a 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -96,6 +96,7 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.ssCommand; +import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; @@ -130,6 +131,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private static final String TEMPLATE_ROOT_DIR = "template/tmpl"; private static final String SNAPSHOT_ROOT_DIR = "snapshots"; + private static final String VOLUME_ROOT_DIR = "volumes"; int _timeout; @@ -323,6 +325,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR); } + @SuppressWarnings("unchecked") + protected String determineS3VolumeDirectory(final Long accountId, final Long volId) { + return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR); + } + @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, String dataPath) { @@ -401,10 +408,18 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } final String bucket = s3.getBucketName(); - // convention is no / in the end for install path based on S3Utils implementation. - String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); - // template key is - // TEMPLATE_ROOT_DIR/account_id/template_id/template_name + String path = null; + if (cmd.getResourceType() == ResourceType.TEMPLATE) { + // convention is no / in the end for install path based on + // S3Utils implementation. + // template key is + // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by adding template_name in the key, I can avoid generating a template.properties file + // for listTemplateCommand. + path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); + } else { + path = determineS3VolumeDirectory(cmd.getAccountId(), cmd.getResourceId()); + } + String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR); S3Utils.putObject(s3, in, bucket, key); List s3Obj = S3Utils.getDirectory(s3, bucket, path); diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 048bd21db7c..50ea160d232 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -132,7 +132,7 @@ public class RequestTest extends TestCase { s_logger.info("Testing Download answer"); VMTemplateVO template = new VMTemplateVO(1, "templatename", ImageFormat.QCOW2, true, true, true, TemplateType.USER, "url", true, 32, 1, "chksum", "displayText", true, 30, true, HypervisorType.KVM, null); - DownloadCommand cmd = new DownloadCommand(new NfsTO("secUrl", DataStoreRole.Image), "secUrl", template, 30000000l); + DownloadCommand cmd = new DownloadCommand(new NfsTO("secUrl", DataStoreRole.Image), template, 30000000l); Request req = new Request(1, 1, cmd, true); req.logD("Debug for Download"); diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index de43e4ba5cf..30549cf5bb1 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -195,125 +195,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor return (downloadsInProgress.size() == 0); } - // TODO: consider using dataMotionStrategy later - /* - @Override - public boolean copyTemplate(VMTemplateVO template, DataStore sourceStore, DataStore destStore) throws StorageUnavailableException { - - boolean downloadJobExists = false; - TemplateDataStoreVO destTmpltStore = null; - TemplateDataStoreVO srcTmpltStore = null; - - srcTmpltStore = this._vmTemplateStoreDao.findByStoreTemplate(sourceStore.getId(), template.getId()); - if (srcTmpltStore == null) { - throw new InvalidParameterValueException("Template " + template.getName() + " not associated with " + sourceStore.getName()); - } - - // generate a storage url on ssvm to copy from - String url = generateCopyUrl(sourceStore, srcTmpltStore); - if (url == null) { - s_logger.warn("Unable to start/resume copy of template " + template.getUniqueName() + " to " + destStore.getName() - + ", no secondary storage vm in running state in source zone"); - throw new CloudRuntimeException("No secondary VM in running state in zone " + sourceStore.getScope().getScopeId()); - } - destTmpltStore = _vmTemplateStoreDao.findByStoreTemplate(destStore.getId(), template.getId()); - if (destTmpltStore == null) { - destTmpltStore = new TemplateDataStoreVO(destStore.getId(), template.getId(), new Date(), 0, - VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, url); - destTmpltStore.setCopy(true); - destTmpltStore.setPhysicalSize(srcTmpltStore.getPhysicalSize()); - _vmTemplateStoreDao.persist(destTmpltStore); - } else if ((destTmpltStore.getJobId() != null) && (destTmpltStore.getJobId().length() > 2)) { - downloadJobExists = true; - } - - Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); - if (srcTmpltStore.getSize() > maxTemplateSizeInBytes) { - throw new CloudRuntimeException("Cant copy the template as the template's size " + srcTmpltStore.getSize() - + " is greater than max.template.iso.size " + maxTemplateSizeInBytes); - } - - if (destTmpltStore != null) { - start(); - String sourceChecksum = this.templateMgr.getChecksum(sourceStore, srcTmpltStore.getInstallPath()); - DownloadCommand dcmd = new DownloadCommand(destStore.getTO(), destStore.getUri(), url, template, - TemplateConstants.DEFAULT_HTTP_AUTH_USER, _copyAuthPasswd, maxTemplateSizeInBytes); - dcmd.setProxy(getHttpProxy()); - if (downloadJobExists) { - dcmd = new DownloadProgressCommand(dcmd, destTmpltStore.getJobId(), RequestType.GET_OR_RESTART); - } - dcmd.setChecksum(sourceChecksum); // We need to set the checksum as - // the source template might be a - // compressed url and have cksum - // for compressed image. Bug - // #10775 - HostVO ssAhost = _ssvmMgr.pickSsvmHost(destStore); - if (ssAhost == null) { - s_logger.warn("There is no secondary storage VM for secondary storage host " + destStore.getName()); - return false; - } - DownloadListener dl = new DownloadListener(ssAhost, destStore, template, _timer, _vmTemplateStoreDao, destTmpltStore.getId(), this, dcmd, - _templateDao, _resourceLimitMgr, _alertMgr, _accountMgr, null); - if (downloadJobExists) { - dl.setCurrState(destTmpltStore.getDownloadState()); - } - DownloadListener old = null; - synchronized (_listenerTemplateMap) { - old = _listenerTemplateMap.put(destTmpltStore, dl); - } - if (old != null) { - old.abandon(); - } - - try { - send(ssAhost.getId(), dcmd, dl); - return true; - } catch (AgentUnavailableException e) { - s_logger.warn("Unable to start /resume COPY of template " + template.getUniqueName() + " to " + destStore.getName(), e); - dl.setDisconnected(); - dl.scheduleStatusCheck(RequestType.GET_OR_RESTART); - e.printStackTrace(); - } - } - - return false; - } - - private String generateCopyUrl(String ipAddress, String dir, String path) { - String hostname = ipAddress; - String scheme = "http"; - if (_sslCopy) { - hostname = ipAddress.replace(".", "-"); - hostname = hostname + ".realhostip.com"; - scheme = "https"; - } - return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path; - } - - private String generateCopyUrl(DataStore sourceServer, TemplateDataStoreVO srcTmpltStore) { - List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, sourceServer - .getScope().getScopeId(), State.Running); - if (ssVms.size() > 0) { - SecondaryStorageVmVO ssVm = ssVms.get(0); - if (ssVm.getPublicIpAddress() == null) { - s_logger.warn("A running secondary storage vm has a null public ip?"); - return null; - } - // get parent path of nfs secondary storage - ImageStoreVO svo = this._imageStoreDao.findById(sourceServer.getId()); - return generateCopyUrl(ssVm.getPublicIpAddress(), svo.getParent(), srcTmpltStore.getInstallPath()); - } - - VMTemplateVO tmplt = _templateDao.findById(srcTmpltStore.getTemplateId()); - HypervisorType hyperType = tmplt.getHypervisorType(); - - if (hyperType != null && hyperType == HypervisorType.KVM) { - //return "file://" + sourceServer.getParent() + "/" + srcTmpltStore.getInstallPath(); - return "file://" + "/" + srcTmpltStore.getInstallPath(); - } - return null; - }*/ - private void initiateTemplateDownload(DataObject template, DataStore store, AsyncCompletionCallback callback) { boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; @@ -330,11 +211,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } Long maxTemplateSizeInBytes = getMaxTemplateSizeInBytes(); - String secUrl = store.getUri(); if (vmTemplateStore != null) { start(); VirtualMachineTemplate tmpl = this._templateDao.findById(template.getId()); - DownloadCommand dcmd = new DownloadCommand(store.getTO(), secUrl, tmpl, maxTemplateSizeInBytes); + DownloadCommand dcmd = new DownloadCommand(store.getTO(), tmpl, maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); @@ -402,11 +282,10 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } Long maxVolumeSizeInBytes = getMaxVolumeSizeInBytes(); - String secUrl = store.getUri(); if (volumeHost != null) { start(); Volume vol = this._volumeDao.findById(volume.getId()); - DownloadCommand dcmd = new DownloadCommand(secUrl, vol, maxVolumeSizeInBytes, checkSum, url, format); + DownloadCommand dcmd = new DownloadCommand(store.getTO(), vol, maxVolumeSizeInBytes, checkSum, url, format); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); @@ -442,108 +321,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } - @DB - public void handleDownloadEvent(HostVO host, DataObject object, Status dnldStatus) { - /* if ((dnldStatus == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) || (dnldStatus == Status.ABANDONED)) { - VolumeHostVO volumeHost = new VolumeHostVO(host.getId(), volume.getId()); - synchronized (_listenerVolumeMap) { - _listenerVolumeMap.remove(volumeHost); - } - }*/ - /* - VolumeHostVO volumeHost = _volumeHostDao.findByHostVolume(host.getId(), volume.getId()); - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - if (dnldStatus == Status.DOWNLOADED) { - - // Create usage event - long size = -1; - if (volumeHost != null) { - size = volumeHost.getPhysicalSize(); - volume.setSize(size); - this._volumeDao.update(volume.getId(), volume); - } else { - s_logger.warn("Failed to get size for volume" + volume.getName()); - } - String eventType = EventTypes.EVENT_VOLUME_UPLOAD; - if (volume.getAccountId() != Account.ACCOUNT_ID_SYSTEM) { - UsageEventUtils.publishUsageEvent(eventType, volume.getAccountId(), host.getDataCenterId(), volume.getId(), volume.getName(), null, - 0l, size, volume.getClass().getName(), volume.getUuid()); - } - } else if (dnldStatus == Status.DOWNLOAD_ERROR || dnldStatus == Status.ABANDONED || dnldStatus == Status.UNKNOWN) { - // Decrement the volume and secondary storage space count - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), com.cloud.configuration.Resource.ResourceType.volume); - _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); - } - txn.commit(); - */ - } - - /* - @Override - public void addSystemVMTemplatesToHost(HostVO host, Map templateInfos){ - if ( templateInfos == null ) { - return; - } - Long hostId = host.getId(); - List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - for ( VMTemplateVO tmplt : rtngTmplts ) { - TemplateProp tmpltInfo = templateInfos.get(tmplt.getUniqueName()); - if ( tmpltInfo == null ) { - continue; - } - VMTemplateHostVO tmpltHost = _vmTemplateHostDao.findByHostTemplate(hostId, tmplt.getId()); - if ( tmpltHost == null ) { - tmpltHost = new VMTemplateHostVO(hostId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); - tmpltHost.setSize(tmpltInfo.getSize()); - tmpltHost.setPhysicalSize(tmpltInfo.getPhysicalSize()); - _vmTemplateHostDao.persist(tmpltHost); - } - } - } - */ - - /*@Override - public void cancelAllDownloads(Long templateId) { - List downloadsInProgress = _vmTemplateHostDao.listByTemplateStates(templateId, - VMTemplateHostVO.Status.DOWNLOAD_IN_PROGRESS, VMTemplateHostVO.Status.NOT_DOWNLOADED); - if (downloadsInProgress.size() > 0) { - for (VMTemplateHostVO vmthvo : downloadsInProgress) { - DownloadListener dl = null; - synchronized (_listenerMap) { - dl = _listenerMap.remove(vmthvo); - } - if (dl != null) { - dl.abandon(); - s_logger.info("Stopping download of template " + templateId + " to storage server " + vmthvo.getHostId()); - } - } - } - }*/ - - /* - private void checksumSync(long hostId){ - SearchCriteria sc = ReadyTemplateStatesSearch.create(); - sc.setParameters("state", ObjectInDataStoreStateMachine.State.Ready); - sc.setParameters("host_id", hostId); - - List templateHostRefList = _vmTemplateHostDao.search(sc, null); - s_logger.debug("Found " +templateHostRefList.size()+ " templates with no checksum. Will ask for computation"); - for(VMTemplateHostVO templateHostRef : templateHostRefList){ - s_logger.debug("Getting checksum for template - " + templateHostRef.getTemplateId()); - String checksum = this.templateMgr.getChecksum(hostId, templateHostRef.getInstallPath()); - VMTemplateVO template = _templateDao.findById(templateHostRef.getTemplateId()); - s_logger.debug("Setting checksum " +checksum+ " for template - " + template.getName()); - template.setChecksum(checksum); - _templateDao.update(template.getId(), template); - } - - } - */ private Long getMaxTemplateSizeInBytes() { try { From c2e9be8d311c2ec6534c311df037b8be7e7756d1 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 26 Apr 2013 16:45:11 -0700 Subject: [PATCH 069/303] Handle DeleteVolumeCommand for S3. --- .../api/storage/DeleteVolumeCommand.java | 13 ++- .../resource/NfsSecondaryStorageResource.java | 100 +++++++++++------- .../CloudStackImageStoreDriverImpl.java | 2 +- .../driver/S3ImageStoreDriverImpl.java | 2 +- .../driver/SwiftImageStoreDriverImpl.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 2 +- 6 files changed, 76 insertions(+), 45 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java b/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java index 949af010423..eb17529e261 100755 --- a/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java +++ b/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java @@ -16,14 +16,17 @@ // under the License. package com.cloud.agent.api.storage; +import com.cloud.agent.api.to.DataStoreTO; + public class DeleteVolumeCommand extends ssCommand { + private DataStoreTO store; private String volumePath; public DeleteVolumeCommand() { } - public DeleteVolumeCommand(String secUrl, String volumePath) { - this.setSecUrl(secUrl); + public DeleteVolumeCommand(DataStoreTO store, String volumePath) { + this.store = store; this.volumePath = volumePath; } @@ -35,4 +38,10 @@ public class DeleteVolumeCommand extends ssCommand { public String getVolumePath() { return volumePath; } + + public DataStoreTO getDataStore() { + return store; + } + + } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 5218933f32a..0806dcfa685 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -1376,7 +1376,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S S3Utils.deleteDirectory(s3, bucket, path); return new Answer(cmd, true, String.format("Deleted template %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String.format("Failed to delete templaet %1$s from bucket %2$s due to the following error: %3$s", + final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); @@ -1405,49 +1405,71 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } protected Answer execute(final DeleteVolumeCommand cmd) { - String relativeVolumePath = cmd.getVolumePath(); - String parent = getRootDir(cmd); + DataStoreTO dstore = cmd.getDataStore(); + if (dstore instanceof NfsTO) { + NfsTO nfs = (NfsTO) dstore; + String relativeVolumePath = cmd.getVolumePath(); + String parent = getRootDir(nfs.getUrl()); - if (relativeVolumePath.startsWith(File.separator)) { - relativeVolumePath = relativeVolumePath.substring(1); - } - - if (!parent.endsWith(File.separator)) { - parent += File.separator; - } - String absoluteVolumePath = parent + relativeVolumePath; - File tmpltParent = new File(absoluteVolumePath).getParentFile(); - String details = null; - if (!tmpltParent.exists()) { - details = "volume parent directory " + tmpltParent.getName() + " doesn't exist"; - s_logger.debug(details); - return new Answer(cmd, true, details); - } - File[] tmpltFiles = tmpltParent.listFiles(); - if (tmpltFiles == null || tmpltFiles.length == 0) { - details = "No files under volume parent directory " + tmpltParent.getName(); - s_logger.debug(details); - } else { - boolean found = false; - for (File f : tmpltFiles) { - if (!found && f.getName().equals("volume.properties")) { - found = true; - } - if (!f.delete()) { - return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath); - } + if (relativeVolumePath.startsWith(File.separator)) { + relativeVolumePath = relativeVolumePath.substring(1); } - if (!found) { - details = "Can not find volume.properties under " + tmpltParent.getName(); + + if (!parent.endsWith(File.separator)) { + parent += File.separator; + } + String absoluteVolumePath = parent + relativeVolumePath; + File tmpltParent = new File(absoluteVolumePath).getParentFile(); + String details = null; + if (!tmpltParent.exists()) { + details = "volume parent directory " + tmpltParent.getName() + " doesn't exist"; s_logger.debug(details); + return new Answer(cmd, true, details); } + File[] tmpltFiles = tmpltParent.listFiles(); + if (tmpltFiles == null || tmpltFiles.length == 0) { + details = "No files under volume parent directory " + tmpltParent.getName(); + s_logger.debug(details); + } else { + boolean found = false; + for (File f : tmpltFiles) { + if (!found && f.getName().equals("volume.properties")) { + found = true; + } + if (!f.delete()) { + return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath); + } + } + if (!found) { + details = "Can not find volume.properties under " + tmpltParent.getName(); + s_logger.debug(details); + } + } + if (!tmpltParent.delete()) { + details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + relativeVolumePath; + s_logger.debug(details); + return new Answer(cmd, false, details); + } + return new Answer(cmd, true, null); + } else if (dstore instanceof S3TO) { + final S3TO s3 = (S3TO) dstore; + final String path = cmd.getVolumePath(); + final String bucket = s3.getBucketName(); + try { + S3Utils.deleteDirectory(s3, bucket, path); + return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket)); + } catch (Exception e) { + final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, + bucket, e.getMessage()); + s_logger.error(errorMessage, e); + return new Answer(cmd, false, errorMessage); + } + } else if (dstore instanceof SwiftTO) { + return new Answer(cmd, false, "Swift is not currently support DeleteVolumeCommand"); + } else { + return new Answer(cmd, false, "Unsupported image data store: " + dstore); } - if (!tmpltParent.delete()) { - details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + relativeVolumePath; - s_logger.debug(details); - return new Answer(cmd, false, details); - } - return new Answer(cmd, true, null); + } Answer execute(CleanupSnapshotBackupCommand cmd) { diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index d3f6916c6a2..1f29dadd74d 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -237,7 +237,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getUri(), volumeStore.getInstallPath()); + store.getTO(), volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 4844167753c..ecd89c74e60 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -195,7 +195,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getUri(), volumeStore.getInstallPath()); + store.getTO(), volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 4fc69484f0f..ddc97866e54 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -189,7 +189,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getUri(), volumeStore.getInstallPath()); + store.getTO(), volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 60ccc2be6fc..ea737b86f5a 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1325,7 +1325,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (installPath != null) { EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getUri(), destroyedStoreVO.getInstallPath()); + DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getTO(), destroyedStoreVO.getInstallPath()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + destroyedStoreVO + " due to " From 5b7ea8b0feeea48dc5bbe7d9e0b45735b83d4404 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 26 Apr 2013 17:52:50 -0700 Subject: [PATCH 070/303] Remove DeleteObjectFromSwiftCommand, which can be achieved through DeleteTemplateCommand. --- .../api/DeleteObjectFromSwiftCommand.java | 61 ------------ .../api/storage/DeleteVolumeCommand.java | 9 +- .../resource/NfsSecondaryStorageResource.java | 92 ++++++++----------- .../CloudStackImageStoreDriverImpl.java | 2 +- .../driver/S3ImageStoreDriverImpl.java | 2 +- .../driver/SwiftImageStoreDriverImpl.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../cloud/storage/swift/SwiftManagerImpl.java | 8 +- 8 files changed, 55 insertions(+), 123 deletions(-) delete mode 100644 api/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java diff --git a/api/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java b/api/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java deleted file mode 100644 index 3d62c507b89..00000000000 --- a/api/src/com/cloud/agent/api/DeleteObjectFromSwiftCommand.java +++ /dev/null @@ -1,61 +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 com.cloud.agent.api; - -import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.agent.api.to.SwiftTO; - -/** - * - * - */ - -public class DeleteObjectFromSwiftCommand extends Command { - @LogLevel(Log4jLevel.Off) - private SwiftTO swift; - private String container; - private String object; - - protected DeleteObjectFromSwiftCommand() { - - } - - public DeleteObjectFromSwiftCommand(SwiftTO swift, String container, String object) { - this.swift = swift; - this.container = container; - this.object = object; - } - - public SwiftTO getSwift() { - return this.swift; - } - - public String getContainer() { - return container; - } - - public String getObject() { - return object; - } - - @Override - public boolean executeInSequence() { - // TODO Auto-generated method stub - return true; - } - -} diff --git a/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java b/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java index eb17529e261..49f0a21967a 100755 --- a/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java +++ b/api/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java @@ -21,12 +21,14 @@ import com.cloud.agent.api.to.DataStoreTO; public class DeleteVolumeCommand extends ssCommand { private DataStoreTO store; private String volumePath; + private Long volumeId; public DeleteVolumeCommand() { } - public DeleteVolumeCommand(DataStoreTO store, String volumePath) { + public DeleteVolumeCommand(DataStoreTO store, Long volumeId, String volumePath) { this.store = store; + this.volumeId = volumeId; this.volumePath = volumePath; } @@ -43,5 +45,10 @@ public class DeleteVolumeCommand extends ssCommand { return store; } + public Long getVolumeId() { + return volumeId; + } + + } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 0806dcfa685..6cb7b9838b5 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -61,7 +61,6 @@ import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.CleanupSnapshotBackupCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.DeleteObjectFromSwiftCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DownloadSnapshotFromS3Command; @@ -215,8 +214,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((uploadTemplateToSwiftFromSecondaryStorageCommand) cmd); } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) { return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd); - } else if (cmd instanceof DeleteObjectFromSwiftCommand) { - return execute((DeleteObjectFromSwiftCommand) cmd); } else if (cmd instanceof CleanupSnapshotBackupCommand) { return execute((CleanupSnapshotBackupCommand) cmd); } else if (cmd instanceof CopyCommand) { @@ -321,7 +318,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } @SuppressWarnings("unchecked") - private String determineS3TemplateNameFromKey(String key){ + private String determineS3TemplateNameFromKey(String key) { return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR); } @@ -330,7 +327,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR); } - @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, String dataPath) { return join(asList(getRootDir(storagePath), dataPath), File.separator); @@ -413,7 +409,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S // convention is no / in the end for install path based on // S3Utils implementation. // template key is - // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by adding template_name in the key, I can avoid generating a template.properties file + // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by + // adding template_name in the key, I can avoid generating a + // template.properties file // for listTemplateCommand. path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); } else { @@ -426,8 +424,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (s3Obj == null || s3Obj.size() == 0) { return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key); } else { - return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj.get(0) - .getETag()); + return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj + .get(0).getETag()); } } else if (dstore instanceof SwiftTO) { // TODO: need to move code from @@ -548,31 +546,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, false, "not supported "); } - private Answer execute(DeleteObjectFromSwiftCommand cmd) { - SwiftTO swift = cmd.getSwift(); - String container = cmd.getContainer(); - String object = cmd.getObject(); - if (object == null) { - object = ""; - } - try { - String result = swiftDelete(swift, container, object); - if (result != null) { - String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result; - s_logger.warn(errMsg); - return new Answer(cmd, false, errMsg); - } - return new Answer(cmd, true, "success"); - } catch (Exception e) { - String errMsg = cmd + " Command failed due to " + e.toString(); - s_logger.warn(errMsg, e); - return new Answer(cmd, false, errMsg); - } - - } - - - String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); @@ -722,6 +695,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return null; } + // TODO: this DeleteSnapshotsDirCommand should be removed after + // SnapshotManager refactor, this is used to delete those snapshot directory + // in the cachestorage. This should be able to be done through + // DeleteSnapshotBackupCommand with deleteAll flag set to true. public Answer execute(DeleteSnapshotsDirCommand cmd) { String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); @@ -804,9 +781,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - - - private String determineSnapshotS3Directory(final Long accountId, final Long volumeId) { return join(S3Utils.SEPARATOR, SNAPSHOT_ROOT_DIR, accountId, volumeId); } @@ -1014,8 +988,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - private String deleteSnapshotBackupfromS3(final S3TO s3, final String secondaryStorageUrl, final Long accountId, final Long volumeId, - final String name, final Boolean deleteAllFlag) { + private String deleteSnapshotBackupfromS3(final S3TO s3, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) { try { @@ -1026,11 +999,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S @Override public String call() throws Exception { - final String innerResult = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, deleteAllFlag); - if (innerResult != null) { - return innerResult; - } - if (deleteAllFlag) { S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId)); } else { @@ -1063,19 +1031,18 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } protected Answer execute(final DeleteSnapshotBackupCommand cmd) { - String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); Long volumeId = cmd.getVolumeId(); String name = cmd.getSnapshotUuid(); DataStoreTO dstore = cmd.getDataStore(); if (dstore instanceof NfsTO) { - final String result = deleteSnapshotBackupFromLocalFileSystem(secondaryStorageUrl, accountId, volumeId, name, cmd.isAll()); + final String result = deleteSnapshotBackupFromLocalFileSystem(((NfsTO) dstore).getUrl(), accountId, volumeId, name, cmd.isAll()); if (result != null) { s_logger.warn(result); return new Answer(cmd, false, result); } } else if (dstore instanceof S3TO) { - final String result = deleteSnapshotBackupfromS3((S3TO) dstore, secondaryStorageUrl, accountId, volumeId, name, cmd.isAll()); + final String result = deleteSnapshotBackupfromS3((S3TO) dstore, accountId, volumeId, name, cmd.isAll()); if (result != null) { s_logger.warn(result); return new Answer(cmd, false, result); @@ -1136,14 +1103,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String bucket = s3.getBucketName(); // List the objects in the source directory on S3 final List objectSummaries = S3Utils.getDirectory(s3, bucket, this.TEMPLATE_ROOT_DIR); - if ( objectSummaries == null ) + if (objectSummaries == null) return null; Map tmpltInfos = new HashMap(); - for (S3ObjectSummary objectSummary : objectSummaries){ + for (S3ObjectSummary objectSummary : objectSummaries) { String key = objectSummary.getKey(); String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); String uniqueName = this.determineS3TemplateNameFromKey(key); - //TODO: isPublic value, where to get? + // TODO: isPublic value, where to get? TemplateProp tInfo = new TemplateProp(uniqueName, installPath, objectSummary.getSize(), objectSummary.getSize(), true, false); tmpltInfos.put(uniqueName, tInfo); } @@ -1158,7 +1125,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { - NfsTO nfs = (NfsTO)store; + NfsTO nfs = (NfsTO) store; String root = getRootDir(nfs.getUrl()); Map templateInfos = _dlMgr.gatherTemplateInfo(root); return new ListTemplateAnswer(nfs.getUrl(), templateInfos); @@ -1324,7 +1291,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S protected Answer execute(final DeleteTemplateCommand cmd) { DataStoreTO dstore = cmd.getDataStore(); if (dstore instanceof NfsTO) { - NfsTO nfs = (NfsTO)dstore; + NfsTO nfs = (NfsTO) dstore; String relativeTemplatePath = cmd.getTemplatePath(); String parent = getRootDir(nfs.getUrl()); @@ -1376,8 +1343,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S S3Utils.deleteDirectory(s3, bucket, path); return new Answer(cmd, true, String.format("Deleted template %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", - path, bucket, e.getMessage()); + final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, + bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -1465,6 +1432,25 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, false, errorMessage); } } else if (dstore instanceof SwiftTO) { + Long volumeId = cmd.getVolumeId(); + String path = cmd.getVolumePath(); + String filename = StringUtils.substringAfterLast(path, "/"); // assuming + // that + // the + // filename + // is + // the + // last + // section + // in + // the + // path + String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId.toString(), filename); + if (result != null) { + String errMsg = "failed to delete volume " + filename + " , err=" + result; + s_logger.warn(errMsg); + return new Answer(cmd, false, errMsg); + } return new Answer(cmd, false, "Swift is not currently support DeleteVolumeCommand"); } else { return new Answer(cmd, false, "Unsupported image data store: " + dstore); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 1f29dadd74d..277cbf9f276 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -237,7 +237,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getTO(), volumeStore.getInstallPath()); + store.getTO(), volumeStore.getVolumeId(), volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index ecd89c74e60..f3aefe06a0d 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -195,7 +195,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getTO(), volumeStore.getInstallPath()); + store.getTO(), volumeStore.getVolumeId(), volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index ddc97866e54..e8009fc0239 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -189,7 +189,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getTO(), volumeStore.getInstallPath()); + store.getTO(), volumeStore.getVolumeId(), volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index ea737b86f5a..e6159679b63 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1325,7 +1325,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (installPath != null) { EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getTO(), destroyedStoreVO.getInstallPath()); + DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getTO(), destroyedStoreVO.getVolumeId(), destroyedStoreVO.getInstallPath()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + destroyedStoreVO + " due to " diff --git a/server/src/com/cloud/storage/swift/SwiftManagerImpl.java b/server/src/com/cloud/storage/swift/SwiftManagerImpl.java index 5a7f01ab20b..75780b8f158 100644 --- a/server/src/com/cloud/storage/swift/SwiftManagerImpl.java +++ b/server/src/com/cloud/storage/swift/SwiftManagerImpl.java @@ -34,7 +34,7 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteObjectFromSwiftCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.to.SwiftTO; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; import com.cloud.configuration.Config; @@ -144,7 +144,7 @@ public class SwiftManagerImpl extends ManagerBase implements SwiftManager { s_logger.warn(msg); throw new CloudRuntimeException(msg); } - Answer answer = _agentMgr.sendToSSVM(null, new DeleteObjectFromSwiftCommand(swift, "T-" + cmd.getId(), null)); + Answer answer = _agentMgr.sendToSSVM(null, new DeleteTemplateCommand(swift, null, cmd.getId(), null)); if (answer == null || !answer.getResult()) { msg = "Failed to delete " + tmpltSwiftRef + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()); s_logger.warn(msg); @@ -170,7 +170,7 @@ public class SwiftManagerImpl extends ManagerBase implements SwiftManager { s_logger.warn(msg); throw new CloudRuntimeException(msg); } - Answer answer = _agentMgr.sendToSSVM(null, new DeleteObjectFromSwiftCommand(swift, "T-" + cmd.getId(), null)); + Answer answer = _agentMgr.sendToSSVM(null, new DeleteTemplateCommand(swift, null, cmd.getId(), null)); if (answer == null || !answer.getResult()) { msg = "Failed to delete " + tmpltSwiftRef + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()); s_logger.warn(msg); @@ -236,7 +236,7 @@ public class SwiftManagerImpl extends ManagerBase implements SwiftManager { if (swift == null) { return null; } - + List tmpltHosts = _vmTmpltHostDao.listByOnlyTemplateId(tmpltId); if (tmpltHosts != null) { Collections.shuffle(tmpltHosts); From 52dfde4a39321154cf1112e4b72f1d293b624a44 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 29 Apr 2013 10:41:31 -0700 Subject: [PATCH 071/303] Fix volume_view to use volume_store_ref instead of previous volume_host_ref. --- setup/db/db/schema-410to420.sql | 101 +++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 7e3704dfd96..f54cf573fa7 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -618,4 +618,103 @@ CREATE VIEW `cloud`.`template_view` AS and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO'); - +DROP VIEW IF EXISTS `cloud`.`volume_view`; +CREATE VIEW `cloud`.`volume_view` AS + select + volumes.id, + volumes.uuid, + volumes.name, + volumes.device_id, + volumes.volume_type, + volumes.size, + volumes.created, + volumes.state, + volumes.attached, + volumes.removed, + volumes.pod_id, + account.id account_id, + account.uuid account_uuid, + account.account_name account_name, + account.type account_type, + domain.id domain_id, + domain.uuid domain_uuid, + domain.name domain_name, + domain.path domain_path, + projects.id project_id, + projects.uuid project_uuid, + projects.name project_name, + data_center.id data_center_id, + data_center.uuid data_center_uuid, + data_center.name data_center_name, + vm_instance.id vm_id, + vm_instance.uuid vm_uuid, + vm_instance.name vm_name, + vm_instance.state vm_state, + vm_instance.vm_type, + user_vm.display_name vm_display_name, + volume_host_ref.size volume_host_size, + volume_host_ref.created volume_host_created, + volume_host_ref.format, + volume_host_ref.download_pct, + volume_host_ref.download_state, + volume_host_ref.error_str, + disk_offering.id disk_offering_id, + disk_offering.uuid disk_offering_uuid, + disk_offering.name disk_offering_name, + disk_offering.display_text disk_offering_display_text, + disk_offering.use_local_storage, + disk_offering.system_use, + storage_pool.id pool_id, + storage_pool.uuid pool_uuid, + storage_pool.name pool_name, + cluster.hypervisor_type, + vm_template.id template_id, + vm_template.uuid template_uuid, + vm_template.extractable, + vm_template.type template_type, + resource_tags.id tag_id, + resource_tags.uuid tag_uuid, + resource_tags.key tag_key, + resource_tags.value tag_value, + resource_tags.domain_id tag_domain_id, + resource_tags.account_id tag_account_id, + resource_tags.resource_id tag_resource_id, + resource_tags.resource_uuid tag_resource_uuid, + resource_tags.resource_type tag_resource_type, + resource_tags.customer tag_customer, + async_job.id job_id, + async_job.uuid job_uuid, + async_job.job_status job_status, + async_job.account_id job_account_id + from + `cloud`.`volumes` + inner join + `cloud`.`account` ON volumes.account_id = account.id + inner join + `cloud`.`domain` ON volumes.domain_id = domain.id + left join + `cloud`.`projects` ON projects.project_account_id = account.id + left join + `cloud`.`data_center` ON volumes.data_center_id = data_center.id + left join + `cloud`.`vm_instance` ON volumes.instance_id = vm_instance.id + left join + `cloud`.`user_vm` ON user_vm.id = vm_instance.id + left join + `cloud`.`volume_store_ref` ON volumes.id = volume_store_ref.volume_id + and volumes.data_center_id = volume_store_ref.zone_id + left join + `cloud`.`disk_offering` ON volumes.disk_offering_id = disk_offering.id + left join + `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id + left join + `cloud`.`cluster` ON storage_pool.cluster_id = cluster.id + left join + `cloud`.`vm_template` ON volumes.template_id = vm_template.id + left join + `cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id + and resource_tags.resource_type = 'Volume' + left join + `cloud`.`async_job` ON async_job.instance_id = volumes.id + and async_job.instance_type = 'Volume' + and async_job.job_status = 0; From ff4c14ca6323eef0e7ab0e174c58d4af4104d958 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 29 Apr 2013 12:10:19 -0700 Subject: [PATCH 072/303] Make old secondary storage APIs backward compatible. --- .../admin/host/AddSecondaryStorageCmd.java | 37 ++++--- .../admin/storage/AddImageStoreCmd.java | 17 ++++ .../api/command/admin/storage/AddS3Cmd.java | 53 ++++++---- .../admin/storage/ListImageStoresCmd.java | 5 + .../api/command/admin/storage/ListS3sCmd.java | 34 ++----- .../api/command/admin/swift/AddSwiftCmd.java | 43 +++++--- .../command/admin/swift/ListSwiftsCmd.java | 26 ++--- .../test/AddSecondaryStorageCmdTest.java | 67 +++++-------- .../api/command/test/AddSwiftCmdTest.java | 97 ------------------- 9 files changed, 135 insertions(+), 244 deletions(-) delete mode 100644 api/test/org/apache/cloudstack/api/command/test/AddSwiftCmdTest.java diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java index 3f243703825..d663575895d 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java @@ -16,25 +16,22 @@ // under the License. package org.apache.cloudstack.api.command.admin.host; -import java.util.List; -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.response.HostResponse; -import org.apache.cloudstack.api.response.RegionResponse; +import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; +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.host.Host; +import com.cloud.storage.ImageStore; import com.cloud.user.Account; -@APICommand(name = "addSecondaryStorage", description="Adds secondary storage.", responseObject=HostResponse.class) +@APICommand(name = "addSecondaryStorage", description="Adds secondary storage.", responseObject=ImageStoreResponse.class) public class AddSecondaryStorageCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(AddSecondaryStorageCmd.class.getName()); private static final String s_name = "addsecondarystorageresponse"; @@ -51,6 +48,7 @@ public class AddSecondaryStorageCmd extends BaseCmd { private Long zoneId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -80,17 +78,19 @@ public class AddSecondaryStorageCmd extends BaseCmd { @Override public void execute(){ - try { - List result = _resourceService.discoverHosts(this); - HostResponse hostResponse = null; - if (result != null && result.size() > 0) { - for (Host host : result) { - // There should only be one secondary storage host per add - hostResponse = _responseGenerator.createHostResponse(host); - hostResponse.setResponseName(getCommandName()); - hostResponse.setObjectName("secondarystorage"); - this.setResponseObject(hostResponse); - } + AddImageStoreCmd cmd = new AddImageStoreCmd(); + cmd.setUrl(this.getUrl()); + cmd.setZoneId(this.getZoneId()); + cmd.setProviderName("CloudStack ImageStore Provider"); + + try{ + ImageStore result = _storageService.discoverImageStore(cmd); + 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"); } @@ -98,6 +98,5 @@ public class AddSecondaryStorageCmd extends BaseCmd { s_logger.warn("Exception: ", ex); throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); } - } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index 7221f4ee90f..190b36a9234 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -78,11 +78,28 @@ public class AddImageStoreCmd extends BaseCmd { return this.providerName; } + public void setUrl(String url) { + this.url = url; + } + + public void setZoneId(Long zoneId) { + this.zoneId = zoneId; + } + + public void setProviderName(String providerName) { + this.providerName = providerName; + } + + public void setDetails(Map details) { + this.details = details; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + + @Override public String getCommandName() { return s_name; diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java index dbd9bff632b..3ad84fd5a51 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddS3Cmd.java @@ -31,12 +31,17 @@ import static org.apache.cloudstack.api.BaseCmd.CommandType.BOOLEAN; import static org.apache.cloudstack.api.BaseCmd.CommandType.INTEGER; import static org.apache.cloudstack.api.BaseCmd.CommandType.STRING; +import java.util.HashMap; +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.response.S3Response; +import org.apache.cloudstack.api.response.ImageStoreResponse; +import org.apache.log4j.Logger; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.DiscoveryException; @@ -44,10 +49,11 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.S3; +import com.cloud.storage.ImageStore; -@APICommand(name = "addS3", description = "Adds S3", responseObject = S3Response.class, since = "4.0.0") +@APICommand(name = "addS3", description = "Adds S3", responseObject = ImageStoreResponse.class, since = "4.0.0") public final class AddS3Cmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(AddS3Cmd.class.getName()); private static String COMMAND_NAME = "adds3response"; @@ -88,26 +94,33 @@ public final class AddS3Cmd extends BaseCmd { ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - final S3 result; + AddImageStoreCmd cmd = new AddImageStoreCmd(); + cmd.setProviderName("S3"); + Map details = new HashMap(); + details.put(ApiConstants.S3_ACCESS_KEY, this.getAccessKey()); + details.put(ApiConstants.S3_SECRET_KEY, this.getSecretKey()); + details.put(ApiConstants.S3_END_POINT, this.getEndPoint()); + details.put(ApiConstants.S3_BUCKET_NAME, this.getBucketName()); + details.put(ApiConstants.S3_HTTPS_FLAG, this.getHttpsFlag().toString()); + details.put(ApiConstants.S3_CONNECTION_TIMEOUT, this.getConnectionTimeout().toString()); + details.put(ApiConstants.S3_MAX_ERROR_RETRY, this.getMaxErrorRetry().toString()); + details.put(ApiConstants.S3_SOCKET_TIMEOUT, this.getSocketTimeout().toString()); - try { - - result = _resourceService.discoverS3(this); - - if (result == null) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add S3."); + try{ + ImageStore result = _storageService.discoverImageStore(cmd); + 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 (DiscoveryException e) { - - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add S3 due to " + e.getMessage()); - + } catch (DiscoveryException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); } - - final S3Response response = _responseGenerator.createS3Response(result); - response.setResponseName(this.getCommandName()); - this.setResponseObject(response); - } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java index 499cc041620..fb589af8e14 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java @@ -83,12 +83,17 @@ public class ListImageStoresCmd extends BaseListCmd { return provider; } + public void setProvider(String provider) { + this.provider = provider; + } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + + @Override public String getCommandName() { return s_name; diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListS3sCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListS3sCmd.java index 4ab71de24d0..409f1607ce7 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListS3sCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListS3sCmd.java @@ -18,23 +18,18 @@ */ package org.apache.cloudstack.api.command.admin.storage; -import java.util.ArrayList; -import java.util.List; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.ListResponse; -import org.apache.cloudstack.api.response.S3Response; - import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.storage.S3; -@APICommand(name = "listS3s", description = "Lists S3s", responseObject = S3Response.class, since = "4.0.0") +@APICommand(name = "listS3s", description = "Lists S3s", responseObject = ImageStoreResponse.class, since = "4.0.0") public class ListS3sCmd extends BaseListCmd { private static final String COMMAND_NAME = "lists3sresponse"; @@ -44,28 +39,11 @@ public class ListS3sCmd extends BaseListCmd { ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - final List result = _resourceService.listS3s(this); - final ListResponse response = new ListResponse(); - final List s3Responses = new ArrayList(); - - if (result != null) { - - for (S3 s3 : result) { - - S3Response s3Response = _responseGenerator.createS3Response(s3); - s3Response.setResponseName(this.getCommandName()); - s3Response.setObjectName("s3"); - s3Responses.add(s3Response); - - } - - } - - response.setResponses(s3Responses); - response.setResponseName(this.getCommandName()); - + ListImageStoresCmd cmd = new ListImageStoresCmd(); + cmd.setProvider("S3"); + ListResponse response = _queryService.searchForImageStores(cmd); + response.setResponseName(getCommandName()); this.setResponseObject(response); - } @Override diff --git a/api/src/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java b/api/src/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java index 364d916add6..462b5297ce5 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/swift/AddSwiftCmd.java @@ -16,21 +16,24 @@ // under the License. package org.apache.cloudstack.api.command.admin.swift; +import java.util.HashMap; +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.response.HostResponse; -import org.apache.cloudstack.api.response.SwiftResponse; +import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.log4j.Logger; import com.cloud.exception.DiscoveryException; -import com.cloud.storage.Swift; +import com.cloud.storage.ImageStore; import com.cloud.user.Account; -@APICommand(name = "addSwift", description = "Adds Swift.", responseObject = HostResponse.class, since="3.0.0") +@APICommand(name = "addSwift", description = "Adds Swift.", responseObject = ImageStoreResponse.class, since="3.0.0") public class AddSwiftCmd extends BaseCmd { public static final Logger s_logger = Logger.getLogger(AddSwiftCmd.class.getName()); private static final String s_name = "addswiftresponse"; @@ -87,21 +90,29 @@ public class AddSwiftCmd extends BaseCmd { @Override public void execute(){ - try { - Swift result = _resourceService.discoverSwift(this); - SwiftResponse swiftResponse = null; - if (result != null) { - swiftResponse = _responseGenerator.createSwiftResponse(result); - swiftResponse.setResponseName(getCommandName()); - swiftResponse.setObjectName("swift"); - this.setResponseObject(swiftResponse); + AddImageStoreCmd cmd = new AddImageStoreCmd(); + cmd.setProviderName("Swift"); + cmd.setUrl(this.getUrl()); + Map details = new HashMap(); + details.put(ApiConstants.ACCOUNT, this.getAccount()); + details.put(ApiConstants.USERNAME, this.getUsername()); + details.put(ApiConstants.KEY, this.getKey()); + + + try{ + ImageStore result = _storageService.discoverImageStore(cmd); + 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 Swift"); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add secondary storage"); } } catch (DiscoveryException ex) { - String errMsg = "Failed to add Swift due to " + ex.toString(); - s_logger.warn(errMsg, ex); - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, errMsg); + s_logger.warn("Exception: ", ex); + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage()); } } } diff --git a/api/src/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java index 7cfe6e1ab7f..b0408f43792 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/swift/ListSwiftsCmd.java @@ -16,23 +16,18 @@ // under the License. package org.apache.cloudstack.api.command.admin.swift; -import java.util.ArrayList; -import java.util.List; - import org.apache.cloudstack.api.APICommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseListCmd; import org.apache.cloudstack.api.Parameter; -import org.apache.cloudstack.api.response.HostResponse; +import org.apache.cloudstack.api.command.admin.storage.ListImageStoresCmd; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.apache.cloudstack.api.response.ListResponse; -import org.apache.cloudstack.api.response.SwiftResponse; import org.apache.log4j.Logger; -import com.cloud.storage.Swift; import com.cloud.user.Account; -import com.cloud.utils.Pair; -@APICommand(name = "listSwifts", description = "List Swift.", responseObject = HostResponse.class, since="3.0.0") +@APICommand(name = "listSwifts", description = "List Swift.", responseObject = ImageStoreResponse.class, since="3.0.0") public class ListSwiftsCmd extends BaseListCmd { public static final Logger s_logger = Logger.getLogger(ListSwiftsCmd.class.getName()); private static final String s_name = "listswiftsresponse"; @@ -65,19 +60,10 @@ public class ListSwiftsCmd extends BaseListCmd { @Override public void execute(){ - Pair, Integer> result = _resourceService.listSwifts(this); - ListResponse response = new ListResponse(); - List swiftResponses = new ArrayList(); - if (result != null) { - for (Swift swift : result.first()) { - SwiftResponse swiftResponse = _responseGenerator.createSwiftResponse(swift); - swiftResponse.setResponseName(getCommandName()); - swiftResponse.setObjectName("swift"); - swiftResponses.add(swiftResponse); - } - } - response.setResponses(swiftResponses, result.second()); + ListImageStoresCmd cmd = new ListImageStoresCmd(); + cmd.setProvider("Swift"); + ListResponse response = _queryService.searchForImageStores(cmd); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/test/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java b/api/test/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java index d6de94dd033..c221ace62cc 100644 --- a/api/test/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java +++ b/api/test/org/apache/cloudstack/api/command/test/AddSecondaryStorageCmdTest.java @@ -21,29 +21,29 @@ import junit.framework.TestCase; import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd; +import org.apache.cloudstack.api.command.admin.storage.AddImageStoreCmd; import org.apache.cloudstack.api.response.HostResponse; +import org.apache.cloudstack.api.response.ImageStoreResponse; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Mockito; -import com.cloud.host.Host; -import com.cloud.resource.ResourceService; - -import edu.emory.mathcs.backport.java.util.Arrays; +import com.cloud.storage.ImageStore; +import com.cloud.storage.StorageService; public class AddSecondaryStorageCmdTest extends TestCase { - private AddSecondaryStorageCmd addSecondaryStorageCmd; + private AddImageStoreCmd addImageStoreCmd; @Rule public ExpectedException expectedException = ExpectedException.none(); + @Override @Before public void setUp() { - addSecondaryStorageCmd = new AddSecondaryStorageCmd() { + addImageStoreCmd = new AddImageStoreCmd() { }; } @@ -51,69 +51,48 @@ public class AddSecondaryStorageCmdTest extends TestCase { @Test public void testExecuteForResult() throws Exception { - ResourceService resourceService = Mockito.mock(ResourceService.class); - addSecondaryStorageCmd._resourceService = resourceService; + StorageService resourceService = Mockito.mock(StorageService.class); + addImageStoreCmd._storageService = resourceService; - Host host = Mockito.mock(Host.class); - Host[] mockHosts = new Host[] { host }; + ImageStore store = Mockito.mock(ImageStore.class); - Mockito.when(resourceService.discoverHosts(addSecondaryStorageCmd)) - .thenReturn(Arrays.asList(mockHosts)); + Mockito.when(resourceService.discoverImageStore(addImageStoreCmd)) + .thenReturn(store); ResponseGenerator responseGenerator = Mockito .mock(ResponseGenerator.class); - addSecondaryStorageCmd._responseGenerator = responseGenerator; + addImageStoreCmd._responseGenerator = responseGenerator; - HostResponse responseHost = new HostResponse(); + ImageStoreResponse responseHost = new ImageStoreResponse(); responseHost.setName("Test"); - Mockito.when(responseGenerator.createHostResponse(host)).thenReturn( + Mockito.when(responseGenerator.createImageStoreResponse(store)).thenReturn( responseHost); - addSecondaryStorageCmd.execute(); + addImageStoreCmd.execute(); - Mockito.verify(responseGenerator).createHostResponse(host); + Mockito.verify(responseGenerator).createImageStoreResponse(store); - HostResponse actualResponse = (HostResponse) addSecondaryStorageCmd + ImageStoreResponse actualResponse = (ImageStoreResponse) addImageStoreCmd .getResponseObject(); Assert.assertEquals(responseHost, actualResponse); - Assert.assertEquals("addsecondarystorageresponse", + Assert.assertEquals("addimagestoreresponse", actualResponse.getResponseName()); } - @Test - public void testExecuteForEmptyResult() throws Exception { - - ResourceService resourceService = Mockito.mock(ResourceService.class); - addSecondaryStorageCmd._resourceService = resourceService; - - Host[] mockHosts = new Host[] {}; - - Mockito.when(resourceService.discoverHosts(addSecondaryStorageCmd)) - .thenReturn(Arrays.asList(mockHosts)); - - try { - addSecondaryStorageCmd.execute(); - } catch (ServerApiException exception) { - Assert.assertEquals("Failed to add secondary storage", - exception.getDescription()); - } - - } - @Test public void testExecuteForNullResult() throws Exception { - ResourceService resourceService = Mockito.mock(ResourceService.class); - addSecondaryStorageCmd._resourceService = resourceService; + StorageService resourceService = Mockito.mock(StorageService.class); + addImageStoreCmd._storageService = resourceService; - Mockito.when(resourceService.discoverHosts(addSecondaryStorageCmd)) + Mockito.when(resourceService.discoverImageStore(addImageStoreCmd)) .thenReturn(null); try { - addSecondaryStorageCmd.execute(); + addImageStoreCmd.execute(); } catch (ServerApiException exception) { Assert.assertEquals("Failed to add secondary storage", exception.getDescription()); diff --git a/api/test/org/apache/cloudstack/api/command/test/AddSwiftCmdTest.java b/api/test/org/apache/cloudstack/api/command/test/AddSwiftCmdTest.java deleted file mode 100644 index 141a2368d78..00000000000 --- a/api/test/org/apache/cloudstack/api/command/test/AddSwiftCmdTest.java +++ /dev/null @@ -1,97 +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.api.command.test; - -import junit.framework.Assert; -import junit.framework.TestCase; - -import org.apache.cloudstack.api.ResponseGenerator; -import org.apache.cloudstack.api.ServerApiException; -import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; -import org.apache.cloudstack.api.response.SwiftResponse; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.Mockito; - -import com.cloud.exception.DiscoveryException; -import com.cloud.resource.ResourceService; -import com.cloud.storage.Swift; - -public class AddSwiftCmdTest extends TestCase { - - private AddSwiftCmd addSwiftCmd; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void setUp() { - addSwiftCmd = new AddSwiftCmd(); - } - - @Test - public void testExecuteSuccess() { - - ResourceService resourceService = Mockito.mock(ResourceService.class); - addSwiftCmd._resourceService = resourceService; - - Swift swift = Mockito.mock(Swift.class); - - try { - Mockito.when(resourceService.discoverSwift(addSwiftCmd)) - .thenReturn(swift); - } catch (DiscoveryException e) { - e.printStackTrace(); - } - - ResponseGenerator responseGenerator = Mockito - .mock(ResponseGenerator.class); - addSwiftCmd._responseGenerator = responseGenerator; - - SwiftResponse swiftResponse = Mockito.mock(SwiftResponse.class); - - Mockito.when(responseGenerator.createSwiftResponse(swift)).thenReturn( - swiftResponse); - - addSwiftCmd.execute(); - - } - - @Test - public void testExecuteFailure() { - - ResourceService resourceService = Mockito.mock(ResourceService.class); - addSwiftCmd._resourceService = resourceService; - try { - Mockito.when(resourceService.discoverSwift(addSwiftCmd)) - .thenReturn(null); - } catch (DiscoveryException e) { - e.printStackTrace(); - } - - try { - addSwiftCmd.execute(); - } catch (ServerApiException exception) { - Assert.assertEquals("Failed to add Swift", - exception.getDescription()); - } - - } - -} From 35264f70878efd47e457bc0543a632721dbb61c9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 29 Apr 2013 17:07:25 -0700 Subject: [PATCH 073/303] Add Download progress support for S3 template/volume download. --- .../agent/api/storage/DownloadCommand.java | 11 - .../resource/NfsSecondaryStorageResource.java | 9 +- .../storage/template/DownloadManager.java | 18 +- .../storage/template/DownloadManagerImpl.java | 84 +++- .../template/S3TemplateDownloader.java | 452 ++++++++++++++++++ utils/src/com/cloud/utils/S3Utils.java | 12 + 6 files changed, 550 insertions(+), 36 deletions(-) create mode 100644 core/src/com/cloud/storage/template/S3TemplateDownloader.java diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/api/src/com/cloud/agent/api/storage/DownloadCommand.java index 8293b445cd7..8abc29a8b6b 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/api/src/com/cloud/agent/api/storage/DownloadCommand.java @@ -108,7 +108,6 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal private long id; private ResourceType resourceType = ResourceType.TEMPLATE; private DataStoreTO _store; - private Long resourceId; protected DownloadCommand() { } @@ -137,7 +136,6 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal this.setSecUrl(((NfsTO) store).getUrl()); } this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; - this.resourceId = template.getId(); } public DownloadCommand(DataStoreTO store, Volume volume, Long maxDownloadSizeInBytes, String checkSum, String url, ImageFormat format) { @@ -148,7 +146,6 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal this._store = store; this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceType = ResourceType.VOLUME; - this.resourceId = volume.getId(); } public DownloadCommand(DataStoreTO store, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { @@ -240,14 +237,6 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal } - public Long getResourceId() { - return resourceId; - } - - - public void setResourceId(Long resourceId) { - this.resourceId = resourceId; - } } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 6cb7b9838b5..efbfaf0db7c 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -377,9 +377,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private Answer execute(DownloadCommand cmd) { DataStoreTO dstore = cmd.getDataStore(); - if (dstore instanceof NfsTO) { + if (dstore instanceof NfsTO || dstore instanceof S3TO ) { return _dlMgr.handleDownloadCommand(this, cmd); - } else if (dstore instanceof S3TO) { + } + /* + else if (dstore instanceof S3TO) { // TODO: start download job to handle this // TODO: how to handle download progress for S3 S3TO s3 = (S3TO) cmd.getDataStore(); @@ -427,7 +429,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj .get(0).getETag()); } - } else if (dstore instanceof SwiftTO) { + } */ + else if (dstore instanceof SwiftTO) { // TODO: need to move code from // execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, // but we need to handle diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java index 82f4153f6e2..ec424aeb817 100644 --- a/core/src/com/cloud/storage/template/DownloadManager.java +++ b/core/src/com/cloud/storage/template/DownloadManager.java @@ -16,13 +16,13 @@ // under the License. package com.cloud.storage.template; -import java.util.List; import java.util.Map; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.to.S3TO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.resource.SecondaryStorageResource; @@ -40,19 +40,21 @@ public interface DownloadManager extends Manager { * @param user username used for authentication to the server * @param password password used for authentication to the server * @param maxDownloadSizeInBytes (optional) max download size for the template, in bytes. - * @param resourceType signifying the type of resource like template, volume etc. + * @param resourceType signifying the type of resource like template, volume etc. * @return job-id that can be used to interrogate the status of the download. */ public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType); - - + + public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType); + + /** * Get the status of a download job * @param jobId job Id * @return status of the download job */ public TemplateDownloader.Status getDownloadStatus(String jobId); - + /** * Get the status of a download job * @param jobId job Id @@ -80,19 +82,19 @@ public interface DownloadManager extends Manager { * @return public String getDownloadLocalPath(String jobId); */ - + /** Handle download commands from the management server * @param cmd cmd from server * @return answer representing status of download. */ public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd); - + /** /** * @return list of template info for installed templates */ public Map gatherTemplateInfo(String templateDir); - + /** /** * @return list of volume info for installed volumes diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 7eb68418b42..c1391a5f7c1 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -61,6 +61,7 @@ import com.cloud.agent.api.storage.DownloadCommand.Proxy; import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.exception.InternalErrorException; import com.cloud.storage.Storage.ImageFormat; @@ -274,15 +275,18 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager threadPool.execute(td); break; case DOWNLOAD_FINISHED: - td.setDownloadError("Download success, starting install "); - String result = postDownload(jobId); - if (result != null) { - s_logger.error("Failed post download script: " + result); - td.setStatus(Status.UNRECOVERABLE_ERROR); - td.setDownloadError("Failed post download script: " + result); - } else { - td.setStatus(Status.POST_DOWNLOAD_FINISHED); - td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); + if (!(td instanceof S3TemplateDownloader)) { + // we currently only create template.properties for NFS by running some post download script + td.setDownloadError("Download success, starting install "); + String result = postDownload(jobId); + if (result != null) { + s_logger.error("Failed post download script: " + result); + td.setStatus(Status.UNRECOVERABLE_ERROR); + td.setDownloadError("Failed post download script: " + result); + } else { + td.setStatus(Status.POST_DOWNLOAD_FINISHED); + td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); + } } dj.cleanup(); break; @@ -456,6 +460,36 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return Status.UNKNOWN; } + @Override + public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + UUID uuid = UUID.randomUUID(); + String jobId = uuid.toString(); + + URI uri; + try { + uri = new URI(url); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("URI is incorrect: " + url); + } + TemplateDownloader td; + if ((uri != null) && (uri.getScheme() != null)) { + if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) { + td = new S3TemplateDownloader(s3, url, installPathPrefix, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, + resourceType); + } else { + throw new CloudRuntimeException("Scheme is not supported " + url); + } + } else { + throw new CloudRuntimeException("Unable to download from URL: " + url); + } + DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); + jobs.put(jobId, dj); + threadPool.execute(td); + + return jobId; + } + + @Override public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); @@ -616,10 +650,26 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } String installPathPrefix = null; - if (ResourceType.TEMPLATE == resourceType){ - installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir; - }else { - installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir; + DataStoreTO dstore = cmd.getDataStore(); + if (dstore instanceof S3TO) { + if (resourceType == ResourceType.TEMPLATE) { + // convention is no / in the end for install path based on + // S3Utils implementation. + // template key is + // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by + // adding template_name in the key, I can avoid generating a + // template.properties file + // for listTemplateCommand. + installPathPrefix = join(asList(_templateDir, cmd.getAccountId(), cmd.getId(), cmd.getName()), S3Utils.SEPARATOR); + } else { + installPathPrefix = join(asList(_volumeDir, cmd.getAccountId(), cmd.getId()), S3Utils.SEPARATOR); + } + } else { + if (ResourceType.TEMPLATE == resourceType) { + installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir; + } else { + installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir; + } } String user = null; @@ -630,7 +680,13 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } //TO DO - Define Volume max size as well long maxDownloadSizeInBytes = (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes()); - String jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + String jobId = null; + if (dstore instanceof S3TO){ + jobId = downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + } + else{ + jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + } sleep(); if (jobId == null) { return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java new file mode 100644 index 00000000000..23f11ab2084 --- /dev/null +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -0,0 +1,452 @@ +// 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.storage.template; + + +import static com.cloud.utils.StringUtils.join; +import static java.util.Arrays.asList; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.Date; + +import org.apache.commons.httpclient.ChunkedInputStream; +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.HttpMethod; +import org.apache.commons.httpclient.HttpMethodRetryHandler; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.NoHttpResponseException; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.apache.log4j.Logger; + +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.ProgressEvent; +import com.amazonaws.services.s3.model.ProgressListener; +import com.amazonaws.services.s3.model.PutObjectRequest; +import com.amazonaws.services.s3.model.StorageClass; +import com.cloud.agent.api.storage.DownloadCommand.Proxy; +import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.to.S3TO; +import com.cloud.utils.Pair; +import com.cloud.utils.S3Utils; + +/** + * Download a template file using HTTP + * + */ +public class S3TemplateDownloader implements TemplateDownloader { + public static final Logger s_logger = Logger.getLogger(S3TemplateDownloader.class.getName()); + private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager(); + + private String downloadUrl; + private String installPath; + private String s3Key; + private String fileName; + public TemplateDownloader.Status status= TemplateDownloader.Status.NOT_STARTED; + public String errorString = " "; + private long remoteSize = 0; + public long downloadTime = 0; + public long totalBytes; + private final HttpClient client; + private GetMethod request; + private boolean resume = false; + private DownloadCompleteCallback completionCallback; + S3TO s3; + boolean inited = true; + + private long MAX_TEMPLATE_SIZE_IN_BYTES; + private ResourceType resourceType = ResourceType.TEMPLATE; + private final HttpMethodRetryHandler myretryhandler; + + + + public S3TemplateDownloader (S3TO storageLayer, String downloadUrl, String installPath, DownloadCompleteCallback callback, long maxTemplateSizeInBytes, String user, String password, Proxy proxy, ResourceType resourceType) { + this.s3 = storageLayer; + this.downloadUrl = downloadUrl; + this.installPath = installPath; + this.status = TemplateDownloader.Status.NOT_STARTED; + this.resourceType = resourceType; + this.MAX_TEMPLATE_SIZE_IN_BYTES = maxTemplateSizeInBytes; + + this.totalBytes = 0; + this.client = new HttpClient(s_httpClientManager); + + myretryhandler = new HttpMethodRetryHandler() { + @Override + public boolean retryMethod( + final HttpMethod method, + final IOException exception, + int executionCount) { + if (executionCount >= 2) { + // Do not retry if over max retry count + return false; + } + if (exception instanceof NoHttpResponseException) { + // Retry if the server dropped connection on us + return true; + } + if (!method.isRequestSent()) { + // Retry if the request has not been sent fully or + // if it's OK to retry methods that have been sent + return true; + } + // otherwise do not retry + return false; + } + }; + + try { + this.request = new GetMethod(downloadUrl); + this.request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler); + this.completionCallback = callback; + + Pair hostAndPort = validateUrl(downloadUrl); + + if (proxy != null) { + client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); + if (proxy.getUserName() != null) { + Credentials proxyCreds = new UsernamePasswordCredentials(proxy.getUserName(), proxy.getPassword()); + client.getState().setProxyCredentials(AuthScope.ANY, proxyCreds); + } + } + if ((user != null) && (password != null)) { + client.getParams().setAuthenticationPreemptive(true); + Credentials defaultcreds = new UsernamePasswordCredentials(user, password); + client.getState().setCredentials(new AuthScope(hostAndPort.first(), hostAndPort.second(), AuthScope.ANY_REALM), defaultcreds); + s_logger.info("Added username=" + user + ", password=" + password + "for host " + hostAndPort.first() + ":" + hostAndPort.second()); + } else { + s_logger.info("No credentials configured for host=" + hostAndPort.first() + ":" + hostAndPort.second()); + } + } catch (IllegalArgumentException iae) { + errorString = iae.getMessage(); + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + inited = false; + } catch (Exception ex){ + errorString = "Unable to start download -- check url? "; + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + s_logger.warn("Exception in constructor -- " + ex.toString()); + } catch (Throwable th) { + s_logger.warn("throwable caught ", th); + } + } + + + private Pair validateUrl(String url) throws IllegalArgumentException { + try { + URI uri = new URI(url); + if (!uri.getScheme().equalsIgnoreCase("http") && !uri.getScheme().equalsIgnoreCase("https") ) { + throw new IllegalArgumentException("Unsupported scheme for url"); + } + int port = uri.getPort(); + if (!(port == 80 || port == 443 || port == -1)) { + throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); + } + + if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { + port = 443; + } else if (port == -1 && uri.getScheme().equalsIgnoreCase("http")) { + port = 80; + } + + URL urlObj = new URL(url); + this.fileName = urlObj.getFile(); + + String host = uri.getHost(); + try { + InetAddress hostAddr = InetAddress.getByName(host); + if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { + throw new IllegalArgumentException("Illegal host specified in url"); + } + if (hostAddr instanceof Inet6Address) { + throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); + } + return new Pair(host, port); + } catch (UnknownHostException uhe) { + throw new IllegalArgumentException("Unable to resolve " + host); + } + + } catch (IllegalArgumentException iae) { + s_logger.warn("Failed uri validation check: " + iae.getMessage()); + throw iae; + } catch (URISyntaxException use) { + s_logger.warn("Failed uri syntax check: " + use.getMessage()); + throw new IllegalArgumentException(use.getMessage()); + } catch (MalformedURLException e) { + s_logger.warn("Failed url syntax check: " + e.getMessage()); + throw new IllegalArgumentException(e.getMessage()); + } + } + + @Override + public long download(boolean resume, DownloadCompleteCallback callback) { + switch (status) { + case ABORTED: + case UNRECOVERABLE_ERROR: + case DOWNLOAD_FINISHED: + return 0; + default: + + } + int bytes=0; + try { + // get the total size of file + Header contentLengthHeader = request.getResponseHeader("Content-Length"); + boolean chunked = false; + long remoteSize2 = 0; + if (contentLengthHeader == null) { + Header chunkedHeader = request.getResponseHeader("Transfer-Encoding"); + if (chunkedHeader == null || !"chunked".equalsIgnoreCase(chunkedHeader.getValue())) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString=" Failed to receive length of download "; + return 0; //FIXME: what status do we put here? Do we retry? + } else if ("chunked".equalsIgnoreCase(chunkedHeader.getValue())){ + chunked = true; + } + } else { + remoteSize2 = Long.parseLong(contentLengthHeader.getValue()); + } + + if (remoteSize == 0) { + remoteSize = remoteSize2; + } + + if (remoteSize > MAX_TEMPLATE_SIZE_IN_BYTES) { + s_logger.info("Remote size is too large: " + remoteSize + " , max=" + MAX_TEMPLATE_SIZE_IN_BYTES); + status = Status.UNRECOVERABLE_ERROR; + errorString = "Download file size is too large"; + return 0; + } + + if (remoteSize == 0) { + remoteSize = MAX_TEMPLATE_SIZE_IN_BYTES; + } + + InputStream in = !chunked?new BufferedInputStream(request.getResponseBodyAsStream()) + : new ChunkedInputStream(request.getResponseBodyAsStream()); + + s_logger.info("Starting download from " + getDownloadUrl() + " to s3 bucket " + s3.getBucketName() + " remoteSize=" + remoteSize + " , max size=" + MAX_TEMPLATE_SIZE_IN_BYTES); + + Date start = new Date(); + // compute s3 key + s3Key = join(asList(installPath, fileName), S3Utils.SEPARATOR); + + // download using S3 API + ObjectMetadata metadata = new ObjectMetadata(); + metadata.setContentLength(remoteSize); + PutObjectRequest putObjectRequest = new PutObjectRequest( + s3.getBucketName(), s3Key, in, metadata) + .withStorageClass(StorageClass.ReducedRedundancy); + // register progress listenser + putObjectRequest + .setProgressListener(new ProgressListener() { + @Override + public void progressChanged( + ProgressEvent progressEvent) { + s_logger.info(progressEvent.getBytesTransfered() + + " number of byte transferd " + + new Date()); + totalBytes += progressEvent.getBytesTransfered(); + if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) { + s_logger.info("download completed"); + status = TemplateDownloader.Status.DOWNLOAD_FINISHED; + } else { + status = TemplateDownloader.Status.IN_PROGRESS; + } + + } + + }); + S3Utils.putObject(s3, putObjectRequest); + Date finish = new Date(); + String downloaded = "(incomplete download)"; + if (totalBytes >= remoteSize) { + status = TemplateDownloader.Status.DOWNLOAD_FINISHED; + downloaded = "(download complete remote=" + remoteSize + "bytes)"; + } + errorString = "Downloaded " + totalBytes + " bytes " + downloaded; + downloadTime += finish.getTime() - start.getTime(); + return totalBytes; + }catch (HttpException hte) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = hte.getMessage(); + } catch (IOException ioe) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; //probably a file write error? + errorString = ioe.getMessage(); + } finally { + // close input stream + request.releaseConnection(); + if (callback != null) { + callback.downloadComplete(status); + } + } + return 0; + } + + public String getDownloadUrl() { + return downloadUrl; + } + + + @Override + public TemplateDownloader.Status getStatus() { + return status; + } + + + @Override + public long getDownloadTime() { + return downloadTime; + } + + + @Override + public long getDownloadedBytes() { + return totalBytes; + } + + @Override + @SuppressWarnings("fallthrough") + public boolean stopDownload() { + switch (getStatus()) { + case IN_PROGRESS: + if (request != null) { + request.abort(); + } + status = TemplateDownloader.Status.ABORTED; + return true; + case UNKNOWN: + case NOT_STARTED: + case RECOVERABLE_ERROR: + case UNRECOVERABLE_ERROR: + case ABORTED: + status = TemplateDownloader.Status.ABORTED; + case DOWNLOAD_FINISHED: + try { + S3Utils.deleteObject(s3, s3.getBucketName(), s3Key); + } catch (Exception ex) { + // ignore delete exception if it is not there + } + return true; + + default: + return true; + } + } + + @Override + public int getDownloadPercent() { + if (remoteSize == 0) { + return 0; + } + + return (int)(100.0*totalBytes/remoteSize); + } + + @Override + public void run() { + try { + download(resume, completionCallback); + } catch (Throwable t) { + s_logger.warn("Caught exception during download "+ t.getMessage(), t); + errorString = "Failed to install: " + t.getMessage(); + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + } + + } + + @Override + public void setStatus(TemplateDownloader.Status status) { + this.status = status; + } + + + + public boolean isResume() { + return resume; + } + + @Override + public String getDownloadError() { + return errorString; + } + + @Override + public String getDownloadLocalPath() { + return this.s3Key; + } + + @Override + public void setResume(boolean resume) { + this.resume = resume; + } + + + @Override + public long getMaxTemplateSizeInBytes() { + return this.MAX_TEMPLATE_SIZE_IN_BYTES; + } + + public static void main(String[] args) { + String url ="http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-noinstall-5.0.77-win32.zip/from/http://mirror.services.wisc.edu/mysql/"; + try { + URI uri = new java.net.URI(url); + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + TemplateDownloader td = new S3TemplateDownloader(null, url,"/tmp/mysql", null, TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES, null, null, null, null); + long bytes = td.download(true, null); + if (bytes > 0) { + System.out.println("Downloaded (" + bytes + " bytes)" + " in " + td.getDownloadTime()/1000 + " secs"); + } else { + System.out.println("Failed download"); + } + + } + + @Override + public void setDownloadError(String error) { + errorString = error; + } + + + + @Override + public boolean isInited() { + return inited; + } + + + public ResourceType getResourceType() { + return resourceType; + } + +} diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index a0eb7d334ea..8199b084e72 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -54,6 +54,7 @@ import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.Bucket; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.utils.exception.CloudRuntimeException; @@ -156,6 +157,17 @@ public final class S3Utils { } + public static void putObject(final ClientOptions clientOptions, + final PutObjectRequest req) { + + assert clientOptions != null; + assert req != null; + + acquireClient(clientOptions).putObject(req); + + } + + // Note that whenever S3Object is returned, client code needs to close the internal stream to avoid resource leak. public static S3Object getObject(final ClientOptions clientOptions, final String bucketName, final String key) { From 37cbe8890faf2a445b6c34b7220978e982651481 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 29 Apr 2013 09:31:52 -0700 Subject: [PATCH 074/303] refactor snapshot --- api/src/com/cloud/storage/Snapshot.java | 7 +- .../com/cloud/storage/VolumeApiService.java | 3 + core/src/com/cloud/storage/SnapshotVO.java | 61 +--- .../com/cloud/storage/VMTemplateHostVO.java | 6 + .../storage/VMTemplateStoragePoolVO.java | 5 + core/src/com/cloud/storage/VolumeHostVO.java | 6 + .../api/storage/DataObjectInStore.java | 1 + .../api/storage/SnapshotDataFactory.java | 4 +- .../subsystem/api/storage/SnapshotInfo.java | 3 + .../subsystem/api/storage/SnapshotResult.java | 25 ++ .../api/storage/SnapshotService.java | 3 +- .../api/storage/SnapshotStrategy.java | 11 + .../subsystem/api/storage/VolumeService.java | 2 + .../storage/command/CreateObjectAnswer.java | 27 +- .../storage/command/CreateObjectCommand.java | 12 +- .../datastore/db/SnapshotDataStoreDao.java | 9 +- .../datastore/db/SnapshotDataStoreVO.java | 47 ++- .../datastore/db/TemplateDataStoreVO.java | 6 +- .../datastore/db/VolumeDataStoreVO.java | 6 + .../storage/to/SnapshotObjectTO.java | 30 ++ .../motion/AncientDataMotionStrategy.java | 57 +--- engine/storage/snapshot/pom.xml | 5 + .../snapshot/SnapshotDataFactoryImpl.java | 37 ++- .../storage/snapshot/SnapshotObject.java | 53 ++-- .../storage/snapshot/SnapshotServiceImpl.java | 277 +++--------------- .../snapshot/SnapshotStrategyBase.java | 24 ++ .../snapshot/XenserverSnapshotStrategy.java | 200 +++++++++++++ .../ObjectInDataStoreManagerImpl.java | 22 +- .../storage/db/ObjectInDataStoreVO.java | 6 + .../image/db/SnapshotDataStoreDaoImpl.java | 45 +-- .../storage/snapshot/SnapshotService.java | 27 -- .../datastore/PrimaryDataStoreImpl.java | 3 +- .../storage/volume/VolumeServiceImpl.java | 21 ++ .../resource/XenServerStorageResource.java | 86 ++---- .../driver/SampleImageStoreDriverImpl.java | 4 +- .../CloudStackPrimaryDataStoreDriverImpl.java | 48 +-- .../cloud/storage/CreateSnapshotPayload.java | 14 + .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../com/cloud/storage/VolumeManagerImpl.java | 44 +++ .../com/cloud/storage/dao/SnapshotDao.java | 3 +- .../cloud/storage/dao/SnapshotDaoImpl.java | 7 +- .../storage/snapshot/SnapshotManager.java | 6 +- .../storage/snapshot/SnapshotManagerImpl.java | 192 +++++++----- 43 files changed, 775 insertions(+), 682 deletions(-) create mode 100644 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java create mode 100644 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java create mode 100644 engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java create mode 100644 engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java create mode 100644 engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java create mode 100644 server/src/com/cloud/storage/CreateSnapshotPayload.java diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java index f71265cd230..0d58a1401bc 100644 --- a/api/src/com/cloud/storage/Snapshot.java +++ b/api/src/com/cloud/storage/Snapshot.java @@ -18,12 +18,13 @@ package com.cloud.storage; import java.util.Date; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.utils.fsm.StateObject; import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.utils.fsm.StateObject; + public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, StateObject { public enum Type { MANUAL, @@ -85,8 +86,6 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, long getVolumeId(); - String getPath(); - String getName(); Date getCreated(); diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 09a07d4be13..2f5364fe525 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -79,4 +79,7 @@ public interface VolumeApiService { Volume attachVolumeToVM(AttachVolumeCmd command); Volume detachVolumeFromVM(DetachVolumeCmd cmmd); + + Snapshot takeSnapshot(Long volumeId, Long policyId) + throws ResourceAllocationException; } diff --git a/core/src/com/cloud/storage/SnapshotVO.java b/core/src/com/cloud/storage/SnapshotVO.java index dbfd7baa617..4fc195cfec4 100644 --- a/core/src/com/cloud/storage/SnapshotVO.java +++ b/core/src/com/cloud/storage/SnapshotVO.java @@ -48,10 +48,6 @@ public class SnapshotVO implements Snapshot { @Column(name="disk_offering_id") Long diskOfferingId; - @Expose - @Column(name="path") - String path; - @Expose @Column(name="name") String name; @@ -76,18 +72,6 @@ public class SnapshotVO implements Snapshot { @Column(name=GenericDao.REMOVED_COLUMN) Date removed; - @Column(name="backup_snap_id") - String backupSnapshotId; - - @Column(name="swift_id") - Long swiftId; - - @Column(name="s3_id") - Long s3Id; - - @Column(name="prev_snap_id") - long prevSnapshotId; - @Column(name="hypervisor_type") @Enumerated(value=EnumType.STRING) HypervisorType hypervisorType; @@ -103,19 +87,17 @@ public class SnapshotVO implements Snapshot { this.uuid = UUID.randomUUID().toString(); } - public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType ) { + public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType ) { this.dataCenterId = dcId; this.accountId = accountId; this.domainId = domainId; this.volumeId = volumeId; this.diskOfferingId = diskOfferingId; - this.path = path; this.name = name; this.snapshotType = snapshotType; this.typeDescription = typeDescription; this.size = size; this.state = State.Allocated; - this.prevSnapshotId = 0; this.hypervisorType = hypervisorType; this.version = "2.2"; this.uuid = UUID.randomUUID().toString(); @@ -153,14 +135,6 @@ public class SnapshotVO implements Snapshot { this.volumeId = volumeId; } - @Override - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } @Override public String getName() { @@ -179,14 +153,6 @@ public class SnapshotVO implements Snapshot { return Type.values()[snapshotType]; } - public Long getSwiftId() { - return swiftId; - } - - public void setSwiftId(Long swiftId) { - this.swiftId = swiftId; - } - @Override public HypervisorType getHypervisorType() { return hypervisorType; @@ -242,22 +208,6 @@ public class SnapshotVO implements Snapshot { this.state = state; } - public String getBackupSnapshotId(){ - return backupSnapshotId; - } - - public long getPrevSnapshotId(){ - return prevSnapshotId; - } - - public void setBackupSnapshotId(String backUpSnapshotId){ - this.backupSnapshotId = backUpSnapshotId; - } - - public void setPrevSnapshotId(long prevSnapshotId){ - this.prevSnapshotId = prevSnapshotId; - } - public static Type getSnapshotType(String snapshotType) { for ( Type type : Type.values()) { if ( type.equals(snapshotType)) { @@ -275,13 +225,4 @@ public class SnapshotVO implements Snapshot { public void setUuid(String uuid) { this.uuid = uuid; } - - public Long getS3Id() { - return s3Id; - } - - public void setS3Id(Long s3Id) { - this.s3Id = s3Id; - } - } diff --git a/core/src/com/cloud/storage/VMTemplateHostVO.java b/core/src/com/cloud/storage/VMTemplateHostVO.java index 8b257598041..227394248b3 100755 --- a/core/src/com/cloud/storage/VMTemplateHostVO.java +++ b/core/src/com/cloud/storage/VMTemplateHostVO.java @@ -31,6 +31,7 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import com.cloud.utils.db.GenericDaoBase; @@ -329,5 +330,10 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj return this.getHostId(); } + @Override + public State getObjectInStoreState() { + return this.state; + } + } diff --git a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java index 638ddd090a6..4c6a758ca90 100644 --- a/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java +++ b/core/src/com/cloud/storage/VMTemplateStoragePoolVO.java @@ -281,5 +281,10 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, return this.getPoolId(); } + @Override + public State getObjectInStoreState() { + return this.state; + } + } diff --git a/core/src/com/cloud/storage/VolumeHostVO.java b/core/src/com/cloud/storage/VolumeHostVO.java index 63b1091059e..a6cd4571fa0 100755 --- a/core/src/com/cloud/storage/VolumeHostVO.java +++ b/core/src/com/cloud/storage/VolumeHostVO.java @@ -32,6 +32,7 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -354,5 +355,10 @@ public class VolumeHostVO implements InternalIdentity, DataObjectInStore { return this.getHostId(); } + @Override + public State getObjectInStoreState() { + return this.state; + } + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java index ded2640bb82..0bfbd9a7aa4 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java @@ -26,4 +26,5 @@ public interface DataObjectInStore extends StateObject, StateDao { - public List listByStoreId(long id); + public List listByStoreId(long id, DataStoreRole role); public void deletePrimaryRecordsForStore(long id); - public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId); + public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId); public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId, boolean lock); - public SnapshotDataStoreVO findBySnapshot(long snapshotId); - - public List listDestroyed(long storeId); + public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index e4c4942862f..af478ab92ba 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -31,10 +31,10 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; -import com.cloud.storage.Storage; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.DataStoreRole; +import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.fsm.StateObject; @@ -51,6 +51,10 @@ public class SnapshotDataStoreVO implements StateObjectcloud-engine-storage ${project.version} + + org.apache.cloudstack + cloud-engine-api + ${project.version} + mysql mysql-connector-java diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java index a647715d47e..c530e4a815e 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java @@ -35,6 +35,9 @@ import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDao; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; +import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -49,36 +52,30 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { VolumeDataFactory volumeFactory; @Override public SnapshotInfo getSnapshot(long snapshotId, DataStore store) { - SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId); + SnapshotVO snapshot = snapshotDao.findById(snapshotId); SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); return so; } - @Override - public SnapshotInfo getSnapshot(long snapshotId) { - SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(snapshotId); - SnapshotObject so = null; - if (snapshot.getState() == Snapshot.State.BackedUp) { - DataStore store = null; - SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId); - if ( snapshotStore != null ){ - store = this.storeMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); - } - so = SnapshotObject.getSnapshotObject(snapshot, store); - } else { - VolumeInfo volume = this.volumeFactory.getVolume(snapshot.getVolumeId()); - so = SnapshotObject.getSnapshotObject(snapshot, volume.getDataStore()); - } - return so; - } - @Override public SnapshotInfo getSnapshot(DataObject obj, DataStore store) { - SnapshotVO snapshot = snapshotDao.findByIdIncludingRemoved(obj.getId()); + SnapshotVO snapshot = snapshotDao.findById(obj.getId()); if (snapshot == null) { throw new CloudRuntimeException("Can't find snapshot: " + obj.getId()); } SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); return so; } + + @Override + public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role) { + SnapshotVO snapshot = snapshotDao.findById(snapshotId); + SnapshotDataStoreVO snapshotStore = snapshotStoreDao.findBySnapshot(snapshotId, role); + if (snapshotStore == null) { + return null; + } + DataStore store = this.storeMgr.getDataStore(snapshotStore.getDataStoreId(), role); + SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); + return so; + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index e22cfb9b3cc..50f3819d543 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -30,7 +30,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -55,6 +59,8 @@ public class SnapshotObject implements SnapshotInfo { @Inject protected SnapshotStateMachineManager stateMachineMgr; @Inject ObjectInDataStoreManager ojbectInStoreMgr; + @Inject + SnapshotDataStoreDao snapshotStore; public SnapshotObject() { } @@ -76,6 +82,7 @@ public class SnapshotObject implements SnapshotInfo { @Override public SnapshotInfo getParent() { + // TODO Auto-generated method stub return null; } @@ -149,11 +156,7 @@ public class SnapshotObject implements SnapshotInfo { @Override public String getPath() { - return this.snapshot.getPath(); - } - - public void setPath(String path) { - this.snapshot.setPath(path); + return this.ojbectInStoreMgr.findObject(this, getDataStore()).getInstallPath(); } @Override @@ -196,9 +199,6 @@ public class SnapshotObject implements SnapshotInfo { return this.snapshot.getDomainId(); } - public void setPrevSnapshotId(Long id) { - this.snapshot.setPrevSnapshotId(id); - } @Override public Long getDataCenterId() { @@ -212,15 +212,8 @@ public class SnapshotObject implements SnapshotInfo { @Override public Long getPrevSnapshotId() { - return this.snapshot.getPrevSnapshotId(); - } - - public void setBackupSnapshotId(String id) { - this.snapshot.setBackupSnapshotId(id); - } - - public String getBackupSnapshotId() { - return this.snapshot.getBackupSnapshotId(); + SnapshotDataStoreVO snapshotStoreVO = this.snapshotStore.findBySnapshot(this.getId(), this.getDataStore().getRole()); + return snapshotStoreVO.getParentSnapshotId(); } public SnapshotVO getSnapshotVO(){ @@ -234,8 +227,28 @@ public class SnapshotObject implements SnapshotInfo { } @Override - public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event, Answer answer) { - // TODO Auto-generated method stub - + public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { + SnapshotDataStoreVO snapshotStore = this.snapshotStore.findByStoreSnapshot(this.getDataStore().getRole(), + this.getDataStore().getId(), this.getId()); + if (answer instanceof CreateObjectAnswer) { + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CreateObjectAnswer) answer).getData(); + snapshotStore.setInstallPath(snapshotTO.getPath()); + this.snapshotStore.update(snapshotStore.getId(), snapshotStore); + } else { + throw new CloudRuntimeException("Unknown answer: " + answer.getClass()); + } + this.processEvent(event); } + + @Override + public ObjectInDataStoreStateMachine.State getStatus() { + return this.ojbectInStoreMgr.findObject(this, store).getObjectInStoreState(); + } + + @Override + public void addPayload(Object data) { + // TODO Auto-generated method stub + + } + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 6674880525e..2fb4609a3c0 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -27,7 +27,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -38,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -51,30 +51,19 @@ import org.springframework.stereotype.Component; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.host.HostVO; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.resource.ResourceManager; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeManager; -import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.snapshot.VMSnapshot; -import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; @Component @@ -92,8 +81,7 @@ public class SnapshotServiceImpl implements SnapshotService { protected SnapshotDao _snapshotDao; @Inject protected SnapshotDataStoreDao _snapshotStoreDao; - @Inject - private ResourceManager _resourceMgr; + @Inject protected SnapshotManager snapshotMgr; @Inject @@ -164,81 +152,24 @@ public class SnapshotServiceImpl implements SnapshotService { CreateSnapshotContext context) { CreateCmdResult result = callback.getResult(); SnapshotObject snapshot = (SnapshotObject)context.snapshot; - VolumeInfo volume = context.volume; AsyncCallFuture future = context.future; - SnapshotResult snapResult = new SnapshotResult(snapshot); + SnapshotResult snapResult = new SnapshotResult(snapshot, result.getAnswer()); if (result.isFailed()) { s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult()); try { snapshot.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException nte) { - s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); + snapshot.processEvent(Event.OperationFailed); + } catch (Exception e) { + s_logger.debug("Failed to update snapshot state due to " + e.getMessage()); } - - + snapResult.setResult(result.getResult()); future.complete(snapResult); return null; } try { - SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); - String preSnapshotPath = null; - if (preSnapshotVO != null) { - preSnapshotPath = preSnapshotVO.getPath(); - } - SnapshotVO snapshotVO = this._snapshotDao.findById(snapshot.getId()); - // The snapshot was successfully created - if (preSnapshotPath != null && preSnapshotPath.equals(result.getPath())) { - // empty snapshot - s_logger.debug("CreateSnapshot: this is empty snapshot "); - - snapshotVO.setPath(preSnapshotPath); - snapshotVO.setBackupSnapshotId(preSnapshotVO.getBackupSnapshotId()); - snapshotVO.setPrevSnapshotId(preSnapshotVO.getId()); - snapshot.processEvent(Snapshot.Event.OperationNotPerformed); - } else { - long preSnapshotId = 0; - - if (preSnapshotVO != null && preSnapshotVO.getBackupSnapshotId() != null) { - preSnapshotId = preSnapshotVO.getId(); - int _deltaSnapshotMax = NumbersUtil.parseInt(_configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX); - int deltaSnap = _deltaSnapshotMax; - - int i; - for (i = 1; i < deltaSnap; i++) { - String prevBackupUuid = preSnapshotVO.getBackupSnapshotId(); - // previous snapshot doesn't have backup, create a full snapshot - if (prevBackupUuid == null) { - preSnapshotId = 0; - break; - } - long preSSId = preSnapshotVO.getPrevSnapshotId(); - if (preSSId == 0) { - break; - } - preSnapshotVO = _snapshotDao.findByIdIncludingRemoved(preSSId); - } - if (i >= deltaSnap) { - preSnapshotId = 0; - } - } - - //If the volume is moved around, backup a full snapshot to secondary storage - if (volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId())) { - preSnapshotId = 0; - //TODO: fix this hack - VolumeVO volumeVO = this.volumeDao.findById(volume.getId()); - volumeVO.setLastPoolId(volume.getPoolId()); - this.volumeDao.update(volume.getId(), volumeVO); - } - - snapshot.setPath(result.getPath()); - snapshot.setPrevSnapshotId(preSnapshotId); - - snapshot.processEvent(Snapshot.Event.OperationSucceeded); - snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(snapshot.getId())); - } + snapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); } catch (Exception e) { s_logger.debug("Failed to create snapshot: ", e); snapResult.setResult(e.toString()); @@ -253,36 +184,49 @@ public class SnapshotServiceImpl implements SnapshotService { return null; } - class SnapshotResult extends CommandResult { - SnapshotInfo snashot; - public SnapshotResult(SnapshotInfo snapshot) { - this.snashot = snapshot; - } - } + - protected SnapshotInfo createSnapshotOnPrimary(VolumeInfo volume, Long snapshotId) { - SnapshotObject snapshot = (SnapshotObject)this.snapshotfactory.getSnapshot(snapshotId); - if (snapshot == null) { - throw new CloudRuntimeException("Can not find snapshot " + snapshotId); + @Override + public SnapshotResult takeSnapshot(SnapshotInfo snap) { + SnapshotObject snapshot = (SnapshotObject)snap; + + SnapshotObject snapshotOnPrimary = null; + try { + snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot); + } catch(Exception e) { + s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage()); + throw new CloudRuntimeException(e); } try { - snapshot.processEvent(Snapshot.Event.CreateRequested); - } catch (NoTransitionException nte) { - s_logger.debug("Failed to update snapshot state due to " + nte.getMessage()); - throw new CloudRuntimeException("Failed to update snapshot state due to " + nte.getMessage()); + snapshotOnPrimary.processEvent(Snapshot.Event.CreateRequested); + } catch (NoTransitionException e) { + s_logger.debug("Failed to change snapshot state: " + e.toString()); + throw new CloudRuntimeException(e); + } + + try { + snapshotOnPrimary.processEvent(Event.CreateOnlyRequested); + } catch (Exception e) { + s_logger.debug("Failed to change snapshot state: " + e.toString()); + try { + snapshotOnPrimary.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change snapshot state: " + e1.toString()); + } + throw new CloudRuntimeException(e); } AsyncCallFuture future = new AsyncCallFuture(); try { CreateSnapshotContext context = new CreateSnapshotContext( - null, volume, snapshot, future); + null, snap.getBaseVolume(), snapshotOnPrimary, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher .create(this); caller.setCallback( caller.getTarget().createSnapshotAsyncCallback(null, null)) .setContext(context); - PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)volume.getDataStore().getDriver(); + PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)snapshotOnPrimary.getDataStore().getDriver(); primaryStore.takeSnapshot(snapshot, caller); } catch (Exception e) { s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); @@ -302,7 +246,7 @@ public class SnapshotServiceImpl implements SnapshotService { s_logger.debug("Failed to create snapshot:" + result.getResult()); throw new CloudRuntimeException(result.getResult()); } - return result.snashot; + return result; } catch (InterruptedException e) { s_logger.debug("Failed to create snapshot", e); throw new CloudRuntimeException("Failed to create snapshot", e); @@ -313,78 +257,11 @@ public class SnapshotServiceImpl implements SnapshotService { } - private boolean hostSupportSnapsthot(HostVO host) { - if (host.getHypervisorType() != HypervisorType.KVM) { - return true; - } - // Determine host capabilities - String caps = host.getCapabilities(); - - if (caps != null) { - String[] tokens = caps.split(","); - for (String token : tokens) { - if (token.contains("snapshot")) { - return true; - } - } - } - return false; - } - - protected boolean supportedByHypervisor(VolumeInfo volume) { - if (volume.getHypervisorType().equals(HypervisorType.KVM)) { - StoragePool storagePool = (StoragePool)volume.getDataStore(); - ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId()); - List hosts = _resourceMgr.listAllHostsInCluster(cluster.getId()); - if (hosts != null && !hosts.isEmpty()) { - HostVO host = hosts.get(0); - if (!hostSupportSnapsthot(host)) { - throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId()); - } - } - } - - // if volume is attached to a vm in destroyed or expunging state; disallow - if (volume.getInstanceId() != null) { - UserVmVO userVm = _vmDao.findById(volume.getInstanceId()); - if (userVm != null) { - if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) { - throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in " - + userVm.getState().toString() + " state"); - } - - if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) { - List activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); - if(activeSnapshots.size() > 1) - throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); - } - - List activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), - VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging); - if (activeVMSnapshots.size() > 0) { - throw new CloudRuntimeException( - "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later"); - } - } - } - - return true; - } - - @Override - public SnapshotInfo takeSnapshot(VolumeInfo volume, Long snapshotId) { - - supportedByHypervisor(volume); - - SnapshotInfo snapshot = createSnapshotOnPrimary(volume, snapshotId); - return snapshot; - } - @Override public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { SnapshotObject snapObj = (SnapshotObject)snapshot; AsyncCallFuture future = new AsyncCallFuture(); - SnapshotResult result = new SnapshotResult(snapshot); + SnapshotResult result = new SnapshotResult(snapshot, null); try { snapObj.processEvent(Snapshot.Event.BackupToSecondary); @@ -420,7 +297,7 @@ public class SnapshotServiceImpl implements SnapshotService { try { SnapshotResult res = future.get(); - SnapshotInfo destSnapshot = res.snashot; + SnapshotInfo destSnapshot = res.getSnashot(); return destSnapshot; } catch (InterruptedException e) { s_logger.debug("failed copy snapshot", e); @@ -438,7 +315,7 @@ public class SnapshotServiceImpl implements SnapshotService { SnapshotInfo destSnapshot = context.destSnapshot; SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot; AsyncCallFuture future = context.future; - SnapshotResult snapResult = new SnapshotResult(destSnapshot); + SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer()); if (result.isFailed()) { snapResult.setResult(result.getResult()); future.complete(snapResult); @@ -453,7 +330,7 @@ public class SnapshotServiceImpl implements SnapshotService { objInStoreMgr.update(destSnapshot, Event.OperationSuccessed); srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); - snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId())); + snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), answer); future.complete(snapResult); } catch (Exception e) { s_logger.debug("Failed to update snapshot state", e); @@ -465,7 +342,7 @@ public class SnapshotServiceImpl implements SnapshotService { @DB protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { - SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId()); + SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image); if ( snapshotStore == null ){ s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); return false; @@ -510,81 +387,19 @@ public class SnapshotServiceImpl implements SnapshotService { if (result.isFailed()) { s_logger.debug("delete snapshot failed" + result.getResult()); snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); - SnapshotResult res = new SnapshotResult(context.snapshot); + SnapshotResult res = new SnapshotResult(context.snapshot, null); future.complete(res); return null; } snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); - SnapshotResult res = new SnapshotResult(context.snapshot); + SnapshotResult res = new SnapshotResult(context.snapshot, null); future.complete(res); return null; } @Override public boolean deleteSnapshot(SnapshotInfo snapInfo) { - Long snapshotId = snapInfo.getId(); - SnapshotObject snapshot = (SnapshotObject)snapInfo; - - if (!Snapshot.State.BackedUp.equals(snapshot.getState())) { - throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); - } - SnapshotVO lastSnapshot = null; - if (snapshot.getBackupSnapshotId() != null) { - List snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId()); - if (snaps != null && snaps.size() > 1) { - snapshot.setBackupSnapshotId(null); - SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId); - _snapshotDao.update(snapshot.getId(), snapshotVO); - } - } - - _snapshotDao.remove(snapshotId); - - long lastId = snapshotId; - boolean destroy = false; - while (true) { - lastSnapshot = _snapshotDao.findNextSnapshot(lastId); - if (lastSnapshot == null) { - // if all snapshots after this snapshot in this chain are removed, remove those snapshots. - destroy = true; - break; - } - if (lastSnapshot.getRemoved() == null) { - // if there is one child not removed, then can not remove back up snapshot. - break; - } - lastId = lastSnapshot.getId(); - } - if (destroy) { - lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); - while (lastSnapshot.getRemoved() != null) { - String BackupSnapshotId = lastSnapshot.getBackupSnapshotId(); - if (BackupSnapshotId != null) { - List snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId); - if (snaps != null && snaps.size() > 1) { - lastSnapshot.setBackupSnapshotId(null); - _snapshotDao.update(lastSnapshot.getId(), lastSnapshot); - } else { - if (destroySnapshotBackUp(lastSnapshot)) { - - } else { - s_logger.debug("Destroying snapshot backup failed " + lastSnapshot); - break; - } - } - } - lastId = lastSnapshot.getPrevSnapshotId(); - if (lastId == 0) { - break; - } - lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); - } - } - return true; + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java new file mode 100644 index 00000000000..70c30a0359d --- /dev/null +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java @@ -0,0 +1,24 @@ +package org.apache.cloudstack.storage.snapshot; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; + +public abstract class SnapshotStrategyBase implements SnapshotStrategy { + @Inject + SnapshotService snapshotSvr; + //the default strategy is: + //create snapshot, + //backup, then delete snapshot on primary storage + @Override + public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { + return snapshotSvr.takeSnapshot(snapshot).getSnashot(); + } + + @Override + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { + return snapshotSvr.backupSnapshot(snapshot); + } +} diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java new file mode 100644 index 00000000000..0fa044b74aa --- /dev/null +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -0,0 +1,200 @@ +package org.apache.cloudstack.storage.snapshot; + +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.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; + +@Component +public class XenserverSnapshotStrategy extends SnapshotStrategyBase { + private static final Logger s_logger = Logger + .getLogger(XenserverSnapshotStrategy.class); + + @Inject + SnapshotManager snapshotMgr; + @Inject + SnapshotService snapshotSvr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + SnapshotDataStoreDao snapshotStoreDao; + @Inject + ConfigurationDao configDao; + @Inject + SnapshotDataFactory snapshotDataFactory; + + @Override + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { + SnapshotInfo parentSnapshot = snapshot.getParent(); + if (parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) { + s_logger.debug("backup an empty snapshot"); + //don't need to backup this snapshot + SnapshotDataStoreVO parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); + if (parentSnapshotOnBackupStore != null && + parentSnapshotOnBackupStore.getState() == State.Ready) { + DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), + parentSnapshotOnBackupStore.getRole()); + + SnapshotInfo snapshotOnImageStore = (SnapshotInfo)store.create(snapshot); + snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); + + SnapshotObjectTO snapTO = new SnapshotObjectTO(); + snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath()); + CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO); + + snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer); + SnapshotObject snapObj = (SnapshotObject)snapshot; + try { + snapObj.processEvent(Snapshot.Event.OperationNotPerformed); + } catch (NoTransitionException e) { + s_logger.debug("Failed to change state: " + snapshot.getId() + ": " +e.toString()); + throw new CloudRuntimeException(e.toString()); + } + return this.snapshotDataFactory.getSnapshot(snapObj.getId(), store); + } else { + s_logger.debug("parent snapshot hasn't been backed up yet"); + } + } + + //determine full snapshot backup or not + + boolean fullBackup = false; + long preSnapshotId = 0; + if (parentSnapshot != null) { + + preSnapshotId = parentSnapshot.getId(); + int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX); + int deltaSnap = _deltaSnapshotMax; + + int i; + SnapshotDataStoreVO parentSnapshotOnBackupStore = null; + for (i = 1; i < deltaSnap; i++) { + parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); + + Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId(); + + if (prevBackupId == 0) { + break; + } + + parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image); + } + if (i >= deltaSnap) { + fullBackup = true; + } + } + + snapshot.addPayload(fullBackup); + return this.snapshotSvr.backupSnapshot(snapshot); + } + + @Override + public boolean deleteSnapshot(SnapshotInfo snapshot) { + Long snapshotId = snapshot.getId(); + SnapshotObject snapObj = (SnapshotObject)snapshot; + + if (!Snapshot.State.BackedUp.equals(snapshot.getState()) || !Snapshot) { + throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); + } + SnapshotVO lastSnapshot = null; + if (snapshot.getPrevSnapshotId() != null) { + List snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId()); + if (snaps != null && snaps.size() > 1) { + snapshot.setBackupSnapshotId(null); + SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId); + _snapshotDao.update(snapshot.getId(), snapshotVO); + } + } + + _snapshotDao.remove(snapshotId); + + long lastId = snapshotId; + boolean destroy = false; + while (true) { + lastSnapshot = _snapshotDao.findNextSnapshot(lastId); + if (lastSnapshot == null) { + // if all snapshots after this snapshot in this chain are removed, remove those snapshots. + destroy = true; + break; + } + if (lastSnapshot.getRemoved() == null) { + // if there is one child not removed, then can not remove back up snapshot. + break; + } + lastId = lastSnapshot.getId(); + } + if (destroy) { + lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); + while (lastSnapshot.getRemoved() != null) { + String BackupSnapshotId = lastSnapshot.getBackupSnapshotId(); + if (BackupSnapshotId != null) { + List snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId); + if (snaps != null && snaps.size() > 1) { + lastSnapshot.setBackupSnapshotId(null); + _snapshotDao.update(lastSnapshot.getId(), lastSnapshot); + } else { + if (destroySnapshotBackUp(lastSnapshot)) { + + } else { + s_logger.debug("Destroying snapshot backup failed " + lastSnapshot); + break; + } + } + } + lastId = lastSnapshot.getPrevSnapshotId(); + if (lastId == 0) { + break; + } + lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); + } + } + return true; + } + + @Override + public boolean canHandle(SnapshotInfo snapshot) { + if (snapshot.getHypervisorType() == HypervisorType.XenServer) { + return true; + } else { + return false; + } + } + + @Override + public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { + snapshot = snapshotSvr.takeSnapshot(snapshot).getSnashot(); + //TODO: add async + return this.backupSnapshot(snapshot); + } +} diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index b00d1521cf2..7ff22c6aa3f 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -120,6 +120,12 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { if ( obj.getType() == DataObjectType.TEMPLATE){ VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); vo = templatePoolDao.persist(vo); + } else if (obj.getType() == DataObjectType.SNAPSHOT) { + SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); + ss.setSnapshotId(obj.getId()); + ss.setDataStoreId(dataStore.getId()); + ss.setRole(dataStore.getRole()); + ss = snapshotDataStoreDao.persist(ss); } } else { // Image store @@ -137,6 +143,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); ss.setSnapshotId(obj.getId()); ss.setDataStoreId(dataStore.getId()); + ss.setRole(dataStore.getRole()); if (dataStore.getRole() == DataStoreRole.ImageCache) { ss.setInstallPath("/snapshots/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); } @@ -185,7 +192,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return true; } case SNAPSHOT: - SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getId(), objId); + SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), dataStore.getId(), objId); if ( destSnapshotStore != null ){ return snapshotDataStoreDao.remove(destSnapshotStore.getId()); } @@ -262,24 +269,17 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { public DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role) { DataObjectInStore vo = null; - if (role == DataStoreRole.Image) { + if (role == DataStoreRole.Image || role == DataStoreRole.ImageCache) { switch (type){ case TEMPLATE: vo = templateDataStoreDao.findByStoreTemplate(dataStoreId, objId); case SNAPSHOT: - vo = snapshotDataStoreDao.findByStoreSnapshot(dataStoreId, objId); + vo = snapshotDataStoreDao.findByStoreSnapshot(role, dataStoreId, objId); case VOLUME: vo = volumeDataStoreDao.findByStoreVolume(dataStoreId, objId); } } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); - } else if (role == DataStoreRole.ImageCache) { - SearchCriteriaService sc = SearchCriteria2.create(ObjectInDataStoreVO.class); - sc.addAnd(sc.getEntity().getObjectId(), Op.EQ, objId); - sc.addAnd(sc.getEntity().getObjectType(), Op.EQ, type); - sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, dataStoreId); - sc.addAnd(sc.getEntity().getDataStoreRole(), Op.EQ, role); - vo = sc.find(); } else { s_logger.debug("Invalid data or store type: " + type + " " + role); throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role); @@ -298,7 +298,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { case TEMPLATE: vo = templateDataStoreDao.findByTemplate(objId); case SNAPSHOT: - vo = snapshotDataStoreDao.findBySnapshot(objId); + vo = snapshotDataStoreDao.findBySnapshot(objId, role); case VOLUME: vo = volumeDataStoreDao.findByVolume(objId); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index 44b91745d61..5b69251f161 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -32,6 +32,7 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; @@ -191,4 +192,9 @@ public class ObjectInDataStoreVO implements StateObject listByStoreId(long id) { + public List listByStoreId(long id, DataStoreRole role) { SearchCriteria sc = storeSearch.create(); sc.setParameters("store_id", id); - sc.setParameters("destroyed", false); - return listIncludingRemovedBy(sc); + sc.setParameters("store_role", role); + return listBy(sc); } @Override @@ -132,40 +134,19 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = storeSnapshotSearch.create(); sc.setParameters("store_id", storeId); sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("destroyed", false); + sc.setParameters("store_role", role); return findOneIncludingRemovedBy(sc); } - @Override - public SnapshotDataStoreVO findByStoreSnapshot(long storeId, long snapshotId, boolean lock) { - SearchCriteria sc = storeSnapshotSearch.create(); - sc.setParameters("store_id", storeId); - sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("destroyed", false); - if (!lock) - return findOneIncludingRemovedBy(sc); - else - return lockOneRandomRow(sc, true); - } - - @Override - public SnapshotDataStoreVO findBySnapshot(long snapshotId) { + public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role) { SearchCriteria sc = snapshotSearch.create(); sc.setParameters("snapshot_id", snapshotId); - sc.setParameters("destroyed", false); - return findOneIncludingRemovedBy(sc); - } - - @Override - public List listDestroyed(long id) { - SearchCriteria sc = storeSearch.create(); - sc.setParameters("store_id", id); - sc.setParameters("destroyed", true); - return listIncludingRemovedBy(sc); + sc.setParameters("store_role", role); + return findOneBy(sc); } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java b/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java deleted file mode 100644 index f3e5c4aea50..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotService.java +++ /dev/null @@ -1,27 +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.snapshot; - -import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; - -public interface SnapshotService { - public SnapshotEntity getSnapshotEntity(long snapshotId); - public boolean takeSnapshot(SnapshotInfo snapshot); - public boolean revertSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(SnapshotInfo snapshot); -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 4c214c1b72a..8b20b22af2f 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -245,7 +245,8 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { } } } - + } else if (obj.getType() == DataObjectType.SNAPSHOT) { + return objectInStoreMgr.create(obj, this); } return objectInStoreMgr.get(obj, this); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 47d99bd8612..e5876b2e2a3 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -840,5 +840,26 @@ public class VolumeServiceImpl implements VolumeService { return null; } + + @Override + public SnapshotInfo takeSnapshot(VolumeInfo volume) { + VolumeObject vol = (VolumeObject)volume; + vol.stateTransit(Volume.Event.SnapshotRequested); + + SnapshotInfo snapshot = null; + try { + snapshot = this.snapshotMgr.takeSnapshot(volume); + } catch (Exception e) { + s_logger.debug("Take snapshot: " + volume.getId() + " failed: " + e.toString()); + } finally { + if (snapshot != null) { + vol.stateTransit(Volume.Event.OperationSucceeded); + } else { + vol.stateTransit(Volume.Event.OperationFailed); + } + } + + return snapshot; + } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 9f47e0682a3..98527a9a226 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -141,58 +141,22 @@ public class XenServerStorageResource { } protected CreateObjectAnswer getTemplateSize(CreateObjectCommand cmd, String templateUrl) { - Connection conn = hypervisorResource.getConnection(); + /*Connection conn = hypervisorResource.getConnection(); long size = this.getTemplateSize(conn, templateUrl); - return new CreateObjectAnswer(cmd, templateUrl, size); + return new CreateObjectAnswer(cmd, templateUrl, size);*/ + return null; } protected CreateObjectAnswer execute(CreateObjectCommand cmd) { - String uriString = cmd.getObjectUri(); - DecodedDataObject obj = null; - - Connection conn = hypervisorResource.getConnection(); - VDI vdi = null; - boolean result = false; - String errorMsg = null; - - try { - obj = Decoder.decode(uriString); - - DecodedDataStore store = obj.getStore(); - if (obj.getObjType().equalsIgnoreCase("template") && store.getRole().equalsIgnoreCase("image")) { - return getTemplateSize(cmd, obj.getPath()); - } - - long size = obj.getSize(); - String name = obj.getName(); - String storeUuid = store.getUuid(); - SR primaryDataStoreSR = getSRByNameLabel(conn, storeUuid); - vdi = createVdi(conn, name, primaryDataStoreSR, size); - VDI.Record record = vdi.getRecord(conn); - result = true; - return new CreateObjectAnswer(cmd, record.uuid, record.virtualSize); - } catch (BadServerResponse e) { - s_logger.debug("Failed to create volume", e); - errorMsg = e.toString(); - } catch (XenAPIException e) { - s_logger.debug("Failed to create volume", e); - errorMsg = e.toString(); - } catch (XmlRpcException e) { - s_logger.debug("Failed to create volume", e); - errorMsg = e.toString(); - } catch (URISyntaxException e) { - s_logger.debug("Failed to create volume", e); - errorMsg = e.toString(); - } finally { - if (!result && vdi != null) { - try { - deleteVDI(conn, vdi); - } catch (Exception e) { - s_logger.debug("Faled to delete vdi: " + vdi.toString()); - } - } - } - - return new CreateObjectAnswer(cmd, false, errorMsg); + DataTO data = cmd.getData(); + try { + if (data.getObjectType() == DataObjectType.VOLUME) { + return createVolume(data); + } + return new CreateObjectAnswer("not supported type"); + } catch (Exception e) { + s_logger.debug("Failed to create object: " + data.getObjectType() + ": " + e.toString()); + return new CreateObjectAnswer(e.toString()); + } } protected Answer execute(DeleteVolumeCommand cmd) { @@ -735,20 +699,30 @@ public class XenServerStorageResource { return new CopyCmdAnswer("not implemented yet"); } - protected CreateObjectAnswer createVolume(DataTO data) { - /* + protected CreateObjectAnswer createVolume(DataTO data) throws BadServerResponse, XenAPIException, XmlRpcException { + VolumeObjectTO volume = (VolumeObjectTO)data; + + Connection conn = hypervisorResource.getConnection(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)data.getDataStore(); + SR poolSr = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); VDI.Record vdir = new VDI.Record(); - vdir.nameLabel = dskch.getName(); + vdir.nameLabel = volume.getName(); vdir.SR = poolSr; vdir.type = Types.VdiType.USER; - vdir.virtualSize = dskch.getSize(); + vdir.virtualSize = volume.getSize(); + VDI vdi; + vdi = VDI.create(conn, vdir); - VDI.Record vdir; vdir = vdi.getRecord(conn); - s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid);*/ - return null; + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setName(vdir.nameLabel); + newVol.setSize(vdir.virtualSize); + newVol.setPath(vdir.uuid); + + return new CreateObjectAnswer(newVol); } + protected CopyCmdAnswer cloneVolumeFromBaseTemplate(DataTO srcData, DataTO destData) { Connection conn = hypervisorResource.getConnection(); PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index 91f9cd0abe6..e477b570e79 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -96,12 +96,12 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { callback.complete(result); return; } - CreateObjectCommand createCmd = new CreateObjectCommand(data.getUri()); + CreateObjectCommand createCmd = new CreateObjectCommand(data.getTO()); CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd); if (answer.getResult()) { //update imagestorevo - result = new CreateCmdResult(answer.getPath(), null); + result = new CreateCmdResult(null, null); } else { result.setResult(answer.getDetails()); } diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index ea4c5615423..5e82a7eaec1 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -34,6 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver 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.command.CreateObjectCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -108,46 +109,15 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri return null; } - public boolean createVolume( + public Answer createVolume( VolumeInfo volume) throws StorageUnavailableException { if (s_logger.isDebugEnabled()) { s_logger.debug("Creating volume: " + volume); } - - DiskOfferingVO offering = diskOfferingDao.findById(volume.getDiskOfferingId()); - DiskProfile diskProfile = new DiskProfile(volume, offering, - null); - - StoragePool pool = (StoragePool)volume.getDataStore(); - VolumeVO vol = volumeDao.findById(volume.getId()); - if (pool != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Trying to create in " + pool); - } - vol.setPoolId(pool.getId()); - - CreateCommand cmd = new CreateCommand(diskProfile, new StorageFilerTO( - pool)); - - Answer answer = storageMgr.sendToPool(pool, null, cmd); - if (answer.getResult()) { - 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.volumeDao.update(vol.getId(), vol); - return true; - } - - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to create volume " + volume.getId()); - } - return false; + + CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO()); + Answer answer = storageMgr.sendToPool((StoragePool)volume.getDataStore(), null, cmd); + return answer; } @Override @@ -155,9 +125,10 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri AsyncCompletionCallback callback) { // TODO Auto-generated method stub String errMsg = null; + Answer answer = null; if (data.getType() == DataObjectType.VOLUME) { try { - createVolume((VolumeInfo)data); + answer = createVolume((VolumeInfo)data); } catch (StorageUnavailableException e) { s_logger.debug("failed to create volume", e); errMsg = e.toString(); @@ -166,13 +137,12 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri errMsg = e.toString(); } } - CreateCmdResult result = new CreateCmdResult(null, null); + CreateCmdResult result = new CreateCmdResult(null, answer); if (errMsg != null) { result.setResult(errMsg); } callback.complete(result); - } @Override diff --git a/server/src/com/cloud/storage/CreateSnapshotPayload.java b/server/src/com/cloud/storage/CreateSnapshotPayload.java new file mode 100644 index 00000000000..cafe46c8814 --- /dev/null +++ b/server/src/com/cloud/storage/CreateSnapshotPayload.java @@ -0,0 +1,14 @@ +package com.cloud.storage; + +public class CreateSnapshotPayload { + private Long snapshotPolicyId; + + public Long getSnapshotPolicyId() { + return snapshotPolicyId; + } + + public void setSnapshotPolicyId(Long snapshotPolicyId) { + this.snapshotPolicyId = snapshotPolicyId; + } + +} diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index e6159679b63..05b22576c7a 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1931,7 +1931,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId()); // Verify that there are no live snapshot, template, volume on the image store to be deleted - List snapshots = _snapshotStoreDao.listByStoreId(storeId); + List snapshots = _snapshotStoreDao.listByStoreId(storeId, DataStoreRole.Image); if ( snapshots != null && snapshots.size() > 0 ){ throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!"); } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 57241b1757f..3177a591728 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -85,6 +85,7 @@ import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.consoleproxy.ConsoleProxyManager; import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.ClusterDao; @@ -166,6 +167,7 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; @@ -2463,5 +2465,47 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new CloudRuntimeException("Failed to destroy volume" + volume.getId(), e); } } + + + + + @Override + public Snapshot takeSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException { + Account caller = UserContext.current().getCaller(); + + VolumeInfo volume = this.volFactory.getVolume(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); + } + DataCenter zone = _dcDao.findById(volume.getDataCenterId()); + if (zone == null) { + throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId()); + } + + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { + throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName()); + } + + if (volume.getState() != Volume.State.Ready) { + throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); + } + + if ( volume.getTemplateId() != null ) { + VMTemplateVO template = _templateDao.findById(volume.getTemplateId()); + if( template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM ) { + throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported"); + } + } + + StoragePool storagePool = (StoragePool)volume.getDataStore(); + if (storagePool == null) { + throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it"); + } + + CreateSnapshotPayload payload = new CreateSnapshotPayload(); + payload.setSnapshotPolicyId(policyId); + return this.volService.takeSnapshot(volume); + + } } diff --git a/server/src/com/cloud/storage/dao/SnapshotDao.java b/server/src/com/cloud/storage/dao/SnapshotDao.java index e6aecc7654f..46f2fa9396b 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDao.java +++ b/server/src/com/cloud/storage/dao/SnapshotDao.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.storage.dao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; @@ -29,7 +30,7 @@ public interface SnapshotDao extends GenericDao, StateDao listByVolumeId(long volumeId); List listByVolumeId(Filter filter, long volumeId); SnapshotVO findNextSnapshot(long parentSnapId); - long getLastSnapshot(long volumeId, long snapId); + long getLastSnapshot(long volumeId, DataStoreRole role); List listByVolumeIdType(long volumeId, Type type); List listByVolumeIdIncludingRemoved(long volumeId); List listByBackupUuid(long volumeId, String backupUuid); diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 2dd5da14265..24d4c653aeb 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -28,6 +28,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Event; import com.cloud.storage.Snapshot.State; @@ -55,7 +56,7 @@ import com.cloud.vm.dao.VMInstanceDao; public class SnapshotDaoImpl extends GenericDaoBase implements SnapshotDao { public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName()); //TODO: we should remove these direct sqls - private static final String GET_LAST_SNAPSHOT = "SELECT id FROM snapshots where volume_id = ? AND id != ? AND path IS NOT NULL ORDER BY created DESC"; + private static final String GET_LAST_SNAPSHOT = "SELECT snapshots.id FROM snapshot_store_ref, snapshots where snapshots.id = snapshot_store_ref.snapshot_id AND snapshosts.volume_id = ? AND snapshot_store_ref.role = ? ORDER BY created DESC"; private static final String UPDATE_SNAPSHOT_VERSION = "UPDATE snapshots SET version = ? WHERE volume_id = ? AND version = ?"; private static final String GET_SECHOST_ID = "SELECT store_id FROM snapshots, snapshot_store_ref where snapshots.id = snapshot_store_ref.snapshot_id AND volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1"; private static final String UPDATE_SECHOST_ID = "UPDATE snapshots SET sechost_id = ? WHERE data_center_id = ?"; @@ -212,14 +213,14 @@ public class SnapshotDaoImpl extends GenericDaoBase implements return null; } @Override - public long getLastSnapshot(long volumeId, long snapId) { + public long getLastSnapshot(long volumeId, DataStoreRole role) { Transaction txn = Transaction.currentTxn(); PreparedStatement pstmt = null; String sql = GET_LAST_SNAPSHOT; try { pstmt = txn.prepareAutoCloseStatement(sql); pstmt.setLong(1, volumeId); - pstmt.setLong(2, snapId); + pstmt.setString(2, role.toString()); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { return rs.getLong(1); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index 818133002c9..983b50c3e65 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -18,6 +18,7 @@ package com.cloud.storage.snapshot; import java.util.List; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import com.cloud.agent.api.Answer; @@ -68,7 +69,10 @@ public interface SnapshotManager { Answer sendToPool(Volume vol, Command cmd); - SnapshotVO getParentSnapshot(VolumeInfo volume, Snapshot snapshot); + SnapshotVO getParentSnapshot(VolumeInfo volume); Snapshot backupSnapshot(Long snapshotId); + + SnapshotInfo takeSnapshot(VolumeInfo volume) + throws ResourceAllocationException; } diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 11408f9a779..c18ffa87092 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -38,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -82,7 +83,9 @@ import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; +import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; +import com.cloud.storage.CreateSnapshotPayload; import com.cloud.storage.Snapshot; import com.cloud.storage.Snapshot.Type; import com.cloud.storage.DataStoreRole; @@ -128,8 +131,12 @@ import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.snapshot.VMSnapshot; +import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; @Component @@ -202,6 +209,10 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Inject VolumeDataFactory volFactory; @Inject SnapshotDataFactory snapshotFactory; @Inject EndPointSelector _epSelector; + @Inject + private ResourceManager _resourceMgr; + @Inject + protected List snapshotStrategies; private int _totalRetries; @@ -278,32 +289,25 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, throw new InvalidParameterValueException("Volume is not in ready state"); } - SnapshotInfo snapshot = null; - + boolean backedUp = false; // does the caller have the authority to act on this volume _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume); - - SnapshotInfo snap = this.snapshotFactory.getSnapshot(snapshotId); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Primary); try { - snapshot = this.snapshotSrv.takeSnapshot(volume, snapshotId); - if (snapshot != null) { - postCreateSnapshot(volumeId, snapshot.getId(), policyId); - //Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event - SnapshotVO freshSnapshot = _snapshotDao.findById(snapshot.getId()); - if ((freshSnapshot != null) && backedUp) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), - snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, - volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid()); - } + postCreateSnapshot(volumeId, snapshot.getId(), policyId); + //Check if the snapshot was removed while backingUp. If yes, do not log snapshot create usage event + SnapshotVO freshSnapshot = _snapshotDao.findById(snapshot.getId()); + if ((freshSnapshot != null) && backedUp) { + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), + snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, + volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid()); + } + + _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot); - _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot); - } - if (backup) { - this.backupSnapshot(snapshotId); - } } catch(Exception e) { s_logger.debug("Failed to create snapshot", e); if (backup) { @@ -337,16 +341,11 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Override public Snapshot backupSnapshot(Long snapshotId) { - SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotId); - if (snapshot == null) { - throw new CloudRuntimeException("Can't find snapshot:" + snapshotId); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image); + if (snapshot != null) { + throw new CloudRuntimeException("Already in the backup snapshot:" + snapshotId); } - if (snapshot.getState() == Snapshot.State.BackedUp) { - return snapshot; - } - - return this.snapshotSrv.backupSnapshot(snapshot); } @@ -436,8 +435,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } @Override - public SnapshotVO getParentSnapshot(VolumeInfo volume, Snapshot snapshot) { - long preId = _snapshotDao.getLastSnapshot(volume.getId(), snapshot.getId()); + public SnapshotVO getParentSnapshot(VolumeInfo volume) { + long preId = _snapshotDao.getLastSnapshot(volume.getId(), DataStoreRole.Primary); SnapshotVO preSnapshotVO = null; if (preId != 0 && !(volume.getLastPoolId() != null && !volume.getLastPoolId().equals(volume.getPoolId()))) { @@ -500,15 +499,21 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, Account caller = UserContext.current().getCaller(); // Verify parameters - SnapshotInfo snapshotCheck = this.snapshotFactory.getSnapshot(snapshotId); + SnapshotVO snapshotCheck = this._snapshotDao.findById(snapshotId); if (snapshotCheck == null) { throw new InvalidParameterValueException("unable to find a snapshot with id " + snapshotId); } _accountMgr.checkAccess(caller, null, true, snapshotCheck); - + SnapshotStrategy snapshotStrategy = null; + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshotCheck)) { + snapshotStrategy = strategy; + break; + } + } try { - boolean result = this.snapshotSrv.deleteSnapshot(snapshotCheck); + boolean result = snapshotStrategy.deleteSnapshot(snapshotId); if (result) { if (snapshotCheck.getState() == Snapshot.State.BackedUp) { UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_DELETE, snapshotCheck.getAccountId(), @@ -529,7 +534,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, @Override public String getSecondaryStorageURL(SnapshotVO snapshot) { - SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId()); + SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image); if (snapshotStore != null){ DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); if ( store != null ){ @@ -904,44 +909,76 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, return null; } - @Override - public SnapshotVO allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException { - Account caller = UserContext.current().getCaller(); + + + private boolean hostSupportSnapsthot(HostVO host) { + if (host.getHypervisorType() != HypervisorType.KVM) { + return true; + } + // Determine host capabilities + String caps = host.getCapabilities(); - VolumeVO volume = _volsDao.findById(volumeId); - if (volume == null) { - throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); - } - DataCenter zone = _dcDao.findById(volume.getDataCenterId()); - if (zone == null) { - throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId()); - } - - if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { - throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName()); - } - - if (volume.getState() != Volume.State.Ready) { - throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); - } - - if ( volume.getTemplateId() != null ) { - VMTemplateVO template = _templateDao.findById(volume.getTemplateId()); - if( template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM ) { - throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported"); - } - } - - StoragePoolVO storagePoolVO = _storagePoolDao.findById(volume.getPoolId()); - if (storagePoolVO == null) { - throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it"); - } - - ClusterVO cluster = _clusterDao.findById(storagePoolVO.getClusterId()); + if (caps != null) { + String[] tokens = caps.split(","); + for (String token : tokens) { + if (token.contains("snapshot")) { + return true; + } + } + } + return false; + } + + private boolean supportedByHypervisor(VolumeInfo volume) { + StoragePool storagePool = (StoragePool)volume.getDataStore(); + ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId()); if (cluster != null && cluster.getHypervisorType() == HypervisorType.Ovm) { throw new InvalidParameterValueException("Ovm won't support taking snapshot"); } + + if (volume.getHypervisorType().equals(HypervisorType.KVM)) { + List hosts = _resourceMgr.listAllHostsInCluster(cluster.getId()); + if (hosts != null && !hosts.isEmpty()) { + HostVO host = hosts.get(0); + if (!hostSupportSnapsthot(host)) { + throw new CloudRuntimeException("KVM Snapshot is not supported on cluster: " + host.getId()); + } + } + } + // if volume is attached to a vm in destroyed or expunging state; disallow + if (volume.getInstanceId() != null) { + UserVmVO userVm = _vmDao.findById(volume.getInstanceId()); + if (userVm != null) { + if (userVm.getState().equals(State.Destroyed) || userVm.getState().equals(State.Expunging)) { + throw new CloudRuntimeException("Creating snapshot failed due to volume:" + volume.getId() + " is associated with vm:" + userVm.getInstanceName() + " is in " + + userVm.getState().toString() + " state"); + } + + if(userVm.getHypervisorType() == HypervisorType.VMware || userVm.getHypervisorType() == HypervisorType.KVM) { + List activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp); + if(activeSnapshots.size() > 1) + throw new CloudRuntimeException("There is other active snapshot tasks on the instance to which the volume is attached, please try again later"); + } + + List activeVMSnapshots = _vmSnapshotDao.listByInstanceId(userVm.getId(), + VMSnapshot.State.Creating, VMSnapshot.State.Reverting, VMSnapshot.State.Expunging); + if (activeVMSnapshots.size() > 0) { + throw new CloudRuntimeException( + "There is other active vm snapshot tasks on the instance to which the volume is attached, please try again later"); + } + } + } + + return true; + } + @Override + public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException { + Account caller = UserContext.current().getCaller(); + + supportedByHypervisor(volume); + CreateSnapshotPayload snapInfo = (CreateSnapshotPayload)volume.getpayload(); + Long policyId = snapInfo.getSnapshotPolicyId(); // Verify permissions _accountMgr.checkAccess(caller, null, true, volume); Type snapshotType = getSnapshotType(policyId); @@ -975,14 +1012,13 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } String snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString; - // Create the Snapshot object and save it so we can return it to the - // user - HypervisorType hypervisorType = this._volsDao.getHypervisorType(volumeId); - SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), null, snapshotName, + HypervisorType hypervisorType = volume.getHypervisorType(); + SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName, (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType); + SnapshotVO snapshot = _snapshotDao.persist(snapshotVO); if (snapshot == null) { - throw new CloudRuntimeException("Failed to create snapshot for volume: "+volumeId); + throw new CloudRuntimeException("Failed to create snapshot for volume: " + volume.getId()); } if (backup) { _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, @@ -991,7 +1027,19 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); } - return snapshot; + SnapshotInfo snap = this.snapshotFactory.getSnapshot(snapshot.getId(), volume.getDataStore()); + boolean processed = false; + for (SnapshotStrategy strategy : snapshotStrategies) { + if (strategy.canHandle(snap)) { + processed = true; + snap = strategy.takeSnapshot(snap); + break; + } + } + if (!processed) { + throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshot.getId()); + } + return snap; } @Override From 2f689171e0e989982b3391944eee49acf98f98e1 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 29 Apr 2013 18:50:46 -0700 Subject: [PATCH 075/303] refactor snapshot --- api/src/com/cloud/storage/Snapshot.java | 5 + .../com/cloud/storage/VolumeApiService.java | 5 +- .../user/snapshot/CreateSnapshotCmd.java | 20 +- .../api/storage/SnapshotStrategy.java | 7 +- .../api/storage/StorageCacheManager.java | 7 + .../subsystem/api/storage/VolumeInfo.java | 1 + .../storage/command/CopyCommand.java | 16 +- .../storage/to/SnapshotObjectTO.java | 70 ++- .../cloudstack/storage/to/VolumeObjectTO.java | 10 + .../manager/StorageCacheManagerImpl.java | 14 + .../motion/AncientDataMotionStrategy.java | 378 ++++------------- .../storage/snapshot/SnapshotObject.java | 8 + .../storage/snapshot/SnapshotServiceImpl.java | 2 +- .../SnapshotStateMachineManagerImpl.java | 6 + .../snapshot/SnapshotStrategyBase.java | 4 +- .../snapshot/XenserverSnapshotStrategy.java | 130 +++--- .../ObjectInDataStoreManagerImpl.java | 28 +- .../image/db/SnapshotDataStoreDaoImpl.java | 6 + .../storage/snapshot/SnapshotEntityImpl.java | 6 - .../storage/volume/VolumeObject.java | 17 + .../storage/volume/VolumeServiceImpl.java | 11 +- .../xen/resource/CitrixResourceBase.java | 2 +- .../resource/XenServerStorageResource.java | 397 +++++++++++++++++- .../CloudStackPrimaryDataStoreDriverImpl.java | 26 +- .../cloud/storage/CreateSnapshotPayload.java | 20 + .../com/cloud/storage/VolumeManagerImpl.java | 32 +- .../cloud/storage/dao/SnapshotDaoImpl.java | 4 +- .../storage/snapshot/SnapshotManager.java | 4 - .../storage/snapshot/SnapshotManagerImpl.java | 161 ++++--- .../cloud/template/TemplateManagerImpl.java | 2 +- 30 files changed, 894 insertions(+), 505 deletions(-) diff --git a/api/src/com/cloud/storage/Snapshot.java b/api/src/com/cloud/storage/Snapshot.java index 0d58a1401bc..27a2fe43f9f 100644 --- a/api/src/com/cloud/storage/Snapshot.java +++ b/api/src/com/cloud/storage/Snapshot.java @@ -60,6 +60,9 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, CreatedOnPrimary, BackingUp, BackedUp, + Copying, + Destroying, + Destroyed,//it's a state, user can't see the snapshot from ui, while the snapshot may still exist on the storage Error; public String toString() { @@ -76,6 +79,8 @@ public interface Snapshot extends ControlledEntity, Identity, InternalIdentity, OperationNotPerformed, BackupToSecondary, BackedupToSecondary, + DestroyRequested, + CopyingRequested, OperationSucceeded, OperationFailed } diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 2f5364fe525..462ff6433d1 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -80,6 +80,9 @@ public interface VolumeApiService { Volume detachVolumeFromVM(DetachVolumeCmd cmmd); - Snapshot takeSnapshot(Long volumeId, Long policyId) + Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account) throws ResourceAllocationException; + + Snapshot allocSnapshot(Long volumeId, Long policyId) + throws ResourceAllocationException; } diff --git a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java index 95d76599f70..25cdedd7d87 100644 --- a/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/snapshot/CreateSnapshotCmd.java @@ -152,7 +152,7 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException { - Snapshot snapshot = _snapshotService.allocSnapshot(getVolumeId(), getPolicyId()); + Snapshot snapshot = this._volumeService.allocSnapshot(getVolumeId(), getPolicyId()); if (snapshot != null) { this.setEntityId(snapshot.getId()); this.setEntityUuid(snapshot.getUuid()); @@ -164,14 +164,20 @@ public class CreateSnapshotCmd extends BaseAsyncCreateCmd { @Override public void execute() { UserContext.current().setEventDetails("Volume Id: "+getVolumeId()); - Snapshot snapshot = _snapshotService.createSnapshot(getVolumeId(), getPolicyId(), getEntityId(), _accountService.getAccount(getEntityOwnerId())); - if (snapshot != null) { - SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - } else { + Snapshot snapshot; + try { + snapshot = _volumeService.takeSnapshot(this.getVolumeId(), this.getPolicyId(), this.getEntityId(), _accountService.getAccount(getEntityOwnerId())); + if (snapshot != null) { + SnapshotResponse response = _responseGenerator.createSnapshotResponse(snapshot); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + volumeId); + } + } catch (Exception e) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create snapshot due to an internal error creating snapshot for volume " + volumeId); } + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java index a642b5e4edf..6b90c31a465 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java @@ -3,9 +3,14 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.Snapshot; + public interface SnapshotStrategy { public SnapshotInfo takeSnapshot(SnapshotInfo snapshot); public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); public boolean deleteSnapshot(Long snapshotId); - public boolean canHandle(Snapshot snapshot); + /** + * @param snapshot + * @return + */ + boolean canHandle(Snapshot snapshot); } 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 index 70332c70db8..0aa30d39b1d 100644 --- 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 @@ -22,4 +22,11 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface StorageCacheManager { public DataStore getCacheStorage(Scope scope); public DataObject createCacheObject(DataObject data, Scope scope); + /** only create cache object in db + * @param data + * @param scope + * @return + */ + DataObject getCacheObject(DataObject data, Scope scope); + DataObject deleteCacheObject(DataObject data); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 349325af45d..7165f370bac 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -27,4 +27,5 @@ public interface VolumeInfo extends DataObject, Volume { public Object getpayload(); public HypervisorType getHypervisorType(); public Long getLastPoolId(); + public String getAttachedVmName(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index 5fe1cbed842..5bceb03ff93 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -23,12 +23,12 @@ import com.cloud.agent.api.Command; public class CopyCommand extends Command implements StorageSubSystemCommand { private DataTO srcTO; private DataTO destTO; + private DataTO cacheTO; - - public CopyCommand(DataTO srcUri, DataTO destUri, int timeout) { + public CopyCommand(DataTO srcData, DataTO destData, int timeout) { super(); - this.srcTO = srcUri; - this.destTO = destUri; + this.srcTO = srcData; + this.destTO = destData; this.setWait(timeout); } @@ -45,4 +45,12 @@ public class CopyCommand extends Command implements StorageSubSystemCommand { return true; } + public DataTO getCacheTO() { + return cacheTO; + } + + public void setCacheTO(DataTO cacheTO) { + this.cacheTO = cacheTO; + } + } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java index 38fea16155d..6d98045cc7a 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -2,21 +2,43 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import com.cloud.agent.api.to.DataStoreTO; public class SnapshotObjectTO implements DataTO { private String path; + private VolumeObjectTO volume; + private String parentSnapshotPath; + private DataStoreTO dataStore; + private String vmName; + private String name; + private long id; + + public SnapshotObjectTO() { + + } + + public SnapshotObjectTO(SnapshotInfo snapshot) { + this.path = snapshot.getPath(); + this.setId(snapshot.getId()); + this.volume = (VolumeObjectTO)snapshot.getBaseVolume().getTO(); + this.setVmName(snapshot.getBaseVolume().getAttachedVmName()); + if (snapshot.getParent() != null) { + this.parentSnapshotPath = snapshot.getParent().getPath(); + } + this.dataStore = snapshot.getDataStore().getTO(); + this.setName(snapshot.getName()); + } + @Override public DataObjectType getObjectType() { - // TODO Auto-generated method stub - return null; + return DataObjectType.SNAPSHOT; } @Override public DataStoreTO getDataStore() { - // TODO Auto-generated method stub - return null; + return this.dataStore; } @Override @@ -27,4 +49,44 @@ public class SnapshotObjectTO implements DataTO { public void setPath(String path) { this.path = path; } + + public VolumeObjectTO getVolume() { + return volume; + } + + public void setVolume(VolumeObjectTO volume) { + this.volume = volume; + } + + public String getParentSnapshotPath() { + return parentSnapshotPath; + } + + public void setParentSnapshotPath(String parentSnapshotPath) { + this.parentSnapshotPath = parentSnapshotPath; + } + + public String getVmName() { + return vmName; + } + + public void setVmName(String vmName) { + this.vmName = vmName; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index bf1bb3c8047..4ca1f9b3e59 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -32,6 +32,7 @@ public class VolumeObjectTO implements DataTO { private String name; private long size; private String path; + private Long volumeId; public VolumeObjectTO() { @@ -49,6 +50,7 @@ public class VolumeObjectTO implements DataTO { } //this.name = volume.getName(); this.size = volume.getSize(); + this.setVolumeId(volume.getId()); } public String getUuid() { @@ -103,4 +105,12 @@ public class VolumeObjectTO implements DataTO { this.path = path; } + public Long getVolumeId() { + return volumeId; + } + + public void setVolumeId(Long volumeId) { + this.volumeId = volumeId; + } + } 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 index d2aacdea076..3a445d4d70e 100644 --- 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 @@ -164,10 +164,24 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return null; } + @Override + public DataObject getCacheObject(DataObject data, Scope scope) { + DataStore cacheStore = this.getCacheStorage(scope); + DataObject objOnCacheStore = cacheStore.create(data); + + return objOnCacheStore; + } + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, CreateCacheObjectContext context) { AsyncCallFuture future = context.future; future.complete(callback.getResult()); return null; } + + @Override + public DataObject deleteCacheObject(DataObject data) { + // TODO Auto-generated method stub + return null; + } } \ No newline at end of file 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 index 79ae28964a0..2075ef60b9c 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -60,6 +60,8 @@ 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.CreatePrivateTemplateAnswer; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.configuration.Config; @@ -127,10 +129,6 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @Inject VolumeManager volumeMgr; @Inject - private SwiftManager _swiftMgr; - @Inject - private S3Manager _s3Mgr; - @Inject StorageCacheManager cacheMgr; @Override @@ -179,112 +177,55 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return answer; } } - - 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()); - } + + protected DataObject cacheSnapshotChain(SnapshotInfo snapshot) { + DataObject leafData = null; + while(snapshot != null) { + DataObject cacheData = cacheMgr.createCacheObject(snapshot, snapshot.getDataStore().getScope()); + if (leafData == null) { + leafData = cacheData; } + snapshot = snapshot.getParent(); } + return leafData; + } + + protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) { + + } + + protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) { + SnapshotInfo snapshot = (SnapshotInfo)snapObj; + StoragePool pool = (StoragePool) volObj.getDataStore(); + String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool; - + DataStore store = snapObj.getDataStore(); + DataStoreTO storTO = store.getTO(); + DataObject srcData = snapObj; try { - if (snapshot.getSwiftId() != null && snapshot.getSwiftId() != 0) { - snapshotMgr.downloadSnapshotsFromSwift(snapshot); - } else if (snapshot.getS3Id() != null && snapshot.getS3Id() != 0) { - snapshotMgr.downloadSnapshotsFromS3(snapshot); + if (!(storTO instanceof NfsTO)) { + srcData = cacheSnapshotChain(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); - } + + CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait); + + + Answer answer = this.storageMgr + .sendToPool(pool, cmd); + return answer; } catch (StorageUnavailableException e) { s_logger.error(basicErrMsg, e); throw new CloudRuntimeException(basicErrMsg); } finally { - if (snapshot.getSwiftId() != null) { - snapshotMgr.deleteSnapshotsDirForVolume( - secondaryStoragePoolUrl, dcId, accountId, volumeId); + if (!(storTO instanceof NfsTO)) { + deleteSnapshotCacheChain((SnapshotInfo)srcData); } } } @@ -328,7 +269,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { answer = copyTemplate(srcData, destData); } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.VOLUME) { - answer = copyFromSnapshot(srcData, destData); + answer = copyVolumeFromSnapshot(srcData, destData); } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.TEMPLATE) { answer = createTemplateFromSnapshot(srcData, destData); @@ -359,49 +300,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @DB protected Answer createTemplateFromSnapshot(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(); - DataStore secStore = destData.getDataStore(); - /* - 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 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.getSwiftId() != null && snapshot.getSwiftId() != 0) { - snapshotMgr.downloadSnapshotsFromSwift(snapshot); - } + String value = configDao .getValue(Config.CreatePrivateTemplateFromSnapshotWait .toString()); @@ -410,172 +309,71 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { .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, secStore); - } - - @DB - protected Answer sendCommand(Command cmd, StoragePool pool, - long templateId, long zoneId, DataStore secStore) { - - CreatePrivateTemplateAnswer answer = null; - try { - answer = (CreatePrivateTemplateAnswer) this.storageMgr.sendToPool( - pool, cmd); - } catch (StorageUnavailableException e) { - throw new CloudRuntimeException( - "Failed to execute CreatePrivateTemplateFromSnapshotCommand", - e); + if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + SnapshotInfo snapshot = (SnapshotInfo)srcData; + srcData = cacheSnapshotChain(snapshot); } - 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(secStore, 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); - TemplateDataStoreVO templateHostVO = new TemplateDataStoreVO(secStore.getId(), - 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()); - templateStoreDao.persist(templateHostVO); - txn.close(); + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromsnapshotwait); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); 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(); - DataStore secStore = destObj.getDataStore(); - String secondaryStorageURL = secStore.getUri(); - VMTemplateVO template = this.templateDao.findById(destObj.getId()); - StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore( - volume.getPoolId(), DataStoreRole.Primary); + private Answer createTemplateFromVolume(DataObject srcData, + DataObject destData) { + 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, secStore); - } - - private DataStore getSecHost(long volumeId, long dcId) { - Long id = snapshotDao.getSecHostId(volumeId); - if ( id != null) { - return this.dataStoreMgr.getDataStore(id, DataStoreRole.Image); + + if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + //need to copy it to image cache store + DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _createprivatetemplatefromvolumewait); + EndPoint ep = selector.select(cacheData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } else { + //handle copy it to/from cache store + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromvolumewait); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; } - return this.dataStoreMgr.getImageStore(dcId); } - protected Answer copySnapshot(DataObject srcObject, DataObject destObject) { - SnapshotInfo srcSnapshot = (SnapshotInfo)srcObject; - VolumeInfo baseVolume = srcSnapshot.getBaseVolume(); - Long dcId = baseVolume.getDataCenterId(); - Long accountId = baseVolume.getAccountId(); + protected Answer copySnapshot(DataObject srcData, DataObject destData) { + String value = configDao.getValue(Config.BackupSnapshotWait.toString()); + int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); - DataStore secStore = getSecHost(baseVolume.getId(), baseVolume.getDataCenterId()); - Long secHostId = secStore.getId(); - String secondaryStoragePoolUrl = secStore.getUri(); - 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()); - snapshotVO.setBackupSnapshotId(answer.getBackupSnapshotName()); - // persist an entry in snapshot_store_ref - SnapshotDataStoreVO snapshotStore = new SnapshotDataStoreVO(secStore.getId(), snapshotVO.getId()); - this._snapshotStoreDao.persist(snapshotStore); - if (answer.isFull()) { - snapshotVO.setPrevSnapshotId(0L); - } - this.snapshotDao.update(srcSnapshot.getId(), snapshotVO); - } - return answer; + DataObject cacheData = null; + try { + if (destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); + + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); + cmd.setCacheTO(cacheData.getTO()); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } else { + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } + } catch (Exception e) { + s_logger.debug("copy snasphot failed: " + e.toString()); + if (cacheData != null) { + cacheMgr.deleteCacheObject(cacheData); + } + throw new CloudRuntimeException(e.toString()); + } + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 50f3819d543..6fddcdacbbe 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -30,6 +30,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; @@ -234,6 +235,13 @@ public class SnapshotObject implements SnapshotInfo { SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CreateObjectAnswer) answer).getData(); snapshotStore.setInstallPath(snapshotTO.getPath()); this.snapshotStore.update(snapshotStore.getId(), snapshotStore); + } else if (answer instanceof CopyCmdAnswer) { + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CopyCmdAnswer) answer).getNewData(); + snapshotStore.setInstallPath(snapshotTO.getPath()); + if (snapshotTO.getParentSnapshotPath() == null) { + snapshotStore.setParentSnapshotId(0L); + } + this.snapshotStore.update(snapshotStore.getId(), snapshotStore); } else { throw new CloudRuntimeException("Unknown answer: " + answer.getClass()); } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 2fb4609a3c0..615ed2002f3 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -399,7 +399,7 @@ public class SnapshotServiceImpl implements SnapshotService { @Override public boolean deleteSnapshot(SnapshotInfo snapInfo) { - + return true; } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java index aa1cf684d7a..489ba280e7d 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java @@ -44,6 +44,12 @@ SnapshotStateMachineManager { stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp); stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp); stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.CreatedOnPrimary); + stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying); + stateMachine.addTransition(Snapshot.State.BackedUp, Event.CopyingRequested, Snapshot.State.Copying); + stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp); + stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp); + stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed); + stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, Snapshot.State.Error); stateMachine.registerListener(new SnapshotStateListener()); } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java index 70c30a0359d..fa0006ae76a 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java @@ -9,9 +9,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; public abstract class SnapshotStrategyBase implements SnapshotStrategy { @Inject SnapshotService snapshotSvr; - //the default strategy is: - //create snapshot, - //backup, then delete snapshot on primary storage + @Override public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { return snapshotSvr.takeSnapshot(snapshot).getSnashot(); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 0fa044b74aa..df2264a3a4a 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -27,6 +27,7 @@ import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.exception.CloudRuntimeException; @@ -48,6 +49,8 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { @Inject ConfigurationDao configDao; @Inject + SnapshotDao snapshotDao; + @Inject SnapshotDataFactory snapshotDataFactory; @Override @@ -114,82 +117,72 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { snapshot.addPayload(fullBackup); return this.snapshotSvr.backupSnapshot(snapshot); } + + protected void deleteSnapshotChain(SnapshotInfo snapshot) { + while(snapshot != null) { + SnapshotInfo child = snapshot.getChild(); + SnapshotInfo parent = snapshot.getParent(); + if (child == null) { + if (!parent.getPath().equalsIgnoreCase(snapshot.getPath())) { + this.snapshotSvr.deleteSnapshot(snapshot); + snapshot = parent; + continue; + } + break; + } else { + break; + } + } + } @Override - public boolean deleteSnapshot(SnapshotInfo snapshot) { - Long snapshotId = snapshot.getId(); - SnapshotObject snapObj = (SnapshotObject)snapshot; - - if (!Snapshot.State.BackedUp.equals(snapshot.getState()) || !Snapshot) { + public boolean deleteSnapshot(Long snapshotId) { + SnapshotVO snapshotVO = snapshotDao.findById(snapshotId); + if (snapshotVO.getState() == Snapshot.State.Destroyed) { + return true; + } + + if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) { throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); } if (s_logger.isDebugEnabled()) { s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); } - SnapshotVO lastSnapshot = null; - if (snapshot.getPrevSnapshotId() != null) { - List snaps = _snapshotDao.listByBackupUuid(snapshot.getVolumeId(), snapshot.getBackupSnapshotId()); - if (snaps != null && snaps.size() > 1) { - snapshot.setBackupSnapshotId(null); - SnapshotVO snapshotVO = this._snapshotDao.findById(snapshotId); - _snapshotDao.update(snapshot.getId(), snapshotVO); - } - } + + + //firt mark the snapshot as destroyed, so that ui can't see it, but we may not destroy the snapshot on the storage, as other snaphosts may depend on it. + SnapshotInfo snapshotOnPrimary = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary); + SnapshotObject obj = (SnapshotObject)snapshotOnPrimary; + try { + obj.processEvent(Snapshot.Event.DestroyRequested); + } catch (NoTransitionException e) { + s_logger.debug("Failed to destroy snapshot: " + e.toString()); + return false; + } + + try { + if (snapshotOnPrimary != null) { + deleteSnapshotChain(snapshotOnPrimary); + } - _snapshotDao.remove(snapshotId); - - long lastId = snapshotId; - boolean destroy = false; - while (true) { - lastSnapshot = _snapshotDao.findNextSnapshot(lastId); - if (lastSnapshot == null) { - // if all snapshots after this snapshot in this chain are removed, remove those snapshots. - destroy = true; - break; - } - if (lastSnapshot.getRemoved() == null) { - // if there is one child not removed, then can not remove back up snapshot. - break; - } - lastId = lastSnapshot.getId(); - } - if (destroy) { - lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); - while (lastSnapshot.getRemoved() != null) { - String BackupSnapshotId = lastSnapshot.getBackupSnapshotId(); - if (BackupSnapshotId != null) { - List snaps = _snapshotDao.listByBackupUuid(lastSnapshot.getVolumeId(), BackupSnapshotId); - if (snaps != null && snaps.size() > 1) { - lastSnapshot.setBackupSnapshotId(null); - _snapshotDao.update(lastSnapshot.getId(), lastSnapshot); - } else { - if (destroySnapshotBackUp(lastSnapshot)) { - - } else { - s_logger.debug("Destroying snapshot backup failed " + lastSnapshot); - break; - } - } - } - lastId = lastSnapshot.getPrevSnapshotId(); - if (lastId == 0) { - break; - } - lastSnapshot = _snapshotDao.findByIdIncludingRemoved(lastId); - } + SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image); + if (snapshotOnImage != null) { + deleteSnapshotChain(snapshotOnImage); + } + + obj.processEvent(Snapshot.Event.OperationSucceeded); + } catch (Exception e) { + s_logger.debug("Failed to delete snapshot: " + e.toString()); + try { + obj.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change snapshot state: " + e.toString()); + } } + return true; } - - @Override - public boolean canHandle(SnapshotInfo snapshot) { - if (snapshot.getHypervisorType() == HypervisorType.XenServer) { - return true; - } else { - return false; - } - } @Override public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { @@ -197,4 +190,13 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { //TODO: add async return this.backupSnapshot(snapshot); } + + @Override + public boolean canHandle(Snapshot snapshot) { + if (snapshot.getHypervisorType() == HypervisorType.XenServer) { + return true; + } else { + return false; + } + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 7ff22c6aa3f..3b01475f90b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -84,33 +84,17 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { public ObjectInDataStoreManagerImpl() { stateMachines = new StateMachine2(); - stateMachines.addTransition(State.Allocated, Event.CreateRequested, + stateMachines.addTransition(State.Allocated, Event.CreateOnlyRequested, State.Creating); - stateMachines.addTransition(State.Creating, Event.OperationSuccessed, - State.Created); stateMachines.addTransition(State.Creating, Event.OperationFailed, - State.Failed); - stateMachines.addTransition(State.Failed, Event.CreateRequested, - State.Creating); - stateMachines.addTransition(State.Ready, Event.DestroyRequested, - State.Destroying); - stateMachines.addTransition(State.Destroying, Event.OperationSuccessed, - State.Destroyed); - stateMachines.addTransition(State.Destroying, Event.OperationFailed, - State.Destroying); - stateMachines.addTransition(State.Destroying, Event.DestroyRequested, - State.Destroying); - stateMachines.addTransition(State.Created, Event.CopyingRequested, + State.Allocated); + stateMachines.addTransition(State.Creating, Event.OperationSuccessed, + State.Ready); + stateMachines.addTransition(State.Ready, Event.CopyingRequested, State.Copying); - stateMachines.addTransition(State.Copying, Event.OperationFailed, - State.Created); stateMachines.addTransition(State.Copying, Event.OperationSuccessed, State.Ready); - stateMachines.addTransition(State.Allocated, Event.CreateOnlyRequested, - State.Creating2); - stateMachines.addTransition(State.Creating2, Event.OperationFailed, - State.Allocated); - stateMachines.addTransition(State.Creating2, Event.OperationSuccessed, + stateMachines.addTransition(State.Copying, Event.OperationFailed, State.Ready); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index e95a1f37fc5..11babcbabf3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -149,4 +149,10 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase future; private final DataStore primaryStore; private final DataObject templateOnStore; + private final SnapshotInfo snapshot; public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject vo, DataStore primaryStore, DataObject templateOnStore, - AsyncCallFuture future) { + AsyncCallFuture future, SnapshotInfo snapshot) { super(callback); this.vo = vo; this.future = future; this.primaryStore = primaryStore; this.templateOnStore = templateOnStore; + this.snapshot = snapshot; } @@ -428,7 +430,7 @@ public class VolumeServiceImpl implements VolumeService { @DB protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture future) { VolumeObject vo = (VolumeObject)volume; - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, vo, pd, templateOnPrimaryStore, future); + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, vo, pd, templateOnPrimaryStore, future, null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)) .setContext(context); @@ -497,8 +499,9 @@ public class VolumeServiceImpl implements VolumeService { try { DataObject volumeOnStore = store.create(volume); volume.processEvent(Event.CreateOnlyRequested); + snapshot.processEvent(Event.CopyingRequested); CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, - (VolumeObject)volume, store, volumeOnStore, future); + (VolumeObject)volume, store, volumeOnStore, future, snapshot); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)) .setContext(context); @@ -517,6 +520,7 @@ public class VolumeServiceImpl implements VolumeService { CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); VolumeInfo volume = context.vo; + SnapshotInfo snapshot = context.snapshot; VolumeApiResult apiResult = new VolumeApiResult(volume); Event event = null; if (result.isFailed()) { @@ -528,6 +532,7 @@ public class VolumeServiceImpl implements VolumeService { try { volume.processEvent(event); + snapshot.processEvent(event); } catch (Exception e) { s_logger.debug("create volume from snapshot failed", e); apiResult.setResult(e.toString()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 046827d79b7..cdc8da9e8f9 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -3620,7 +3620,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return false; } - private void swiftBackupSnapshot(Connection conn, SwiftTO swift, String srUuid, String snapshotUuid, String container, Boolean isISCSI, int wait) { + public void swiftBackupSnapshot(Connection conn, SwiftTO swift, String srUuid, String snapshotUuid, String container, Boolean isISCSI, int wait) { String lfilename; String ldir; if ( isISCSI ) { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 98527a9a226..8d762411fad 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -18,12 +18,20 @@ */ package com.cloud.hypervisor.xen.resource; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -43,6 +51,7 @@ import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.http.HttpEntity; @@ -54,18 +63,25 @@ import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.ManageSnapshotAnswer; +import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; +import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.agent.api.to.SwiftTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.DataStoreRole; +import com.cloud.utils.S3Utils; +import com.cloud.utils.StringUtils; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.DecodedDataStore; @@ -80,8 +96,6 @@ import com.xensource.xenapi.Types.BadServerResponse; import com.xensource.xenapi.Types.XenAPIException; import com.xensource.xenapi.VDI; -import edu.emory.mathcs.backport.java.util.Arrays; - public class XenServerStorageResource { private static final Logger s_logger = Logger.getLogger(XenServerStorageResource.class); protected CitrixResourceBase hypervisorResource; @@ -146,12 +160,62 @@ public class XenServerStorageResource { return new CreateObjectAnswer(cmd, templateUrl, size);*/ return null; } + + protected CreateObjectAnswer createSnapshot(SnapshotObjectTO snapshotTO) { + Connection conn = hypervisorResource.getConnection(); + long snapshotId = snapshotTO.getId(); + String snapshotName = snapshotTO.getName(); + String details = "create snapshot operation Failed for snapshotId: " + snapshotId; + String snapshotUUID = null; + + try { + String volumeUUID = snapshotTO.getVolume().getPath(); + VDI volume = VDI.getByUuid(conn, volumeUUID); + + VDI snapshot = volume.snapshot(conn, new HashMap()); + + if (snapshotName != null) { + snapshot.setNameLabel(conn, snapshotName); + } + + snapshotUUID = snapshot.getUuid(conn); + String preSnapshotUUID = snapshotTO.getPath(); + //check if it is a empty snapshot + if( preSnapshotUUID != null) { + SR sr = volume.getSR(conn); + String srUUID = sr.getUuid(conn); + String type = sr.getType(conn); + Boolean isISCSI = IsISCSI(type); + String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI); + + String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI); + if( snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) { + // this is empty snapshot, remove it + snapshot.destroy(conn); + snapshotUUID = preSnapshotUUID; + } + } + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + newSnapshot.setPath(snapshotUUID); + return new CreateObjectAnswer(newSnapshot); + } catch (XenAPIException e) { + details += ", reason: " + e.toString(); + s_logger.warn(details, e); + } catch (Exception e) { + details += ", reason: " + e.toString(); + s_logger.warn(details, e); + } + + return new CreateObjectAnswer(details); + } protected CreateObjectAnswer execute(CreateObjectCommand cmd) { DataTO data = cmd.getData(); try { if (data.getObjectType() == DataObjectType.VOLUME) { return createVolume(data); - } + } else if (data.getObjectType() == DataObjectType.SNAPSHOT) { + return createSnapshot((SnapshotObjectTO)data); + } return new CreateObjectAnswer("not supported type"); } catch (Exception e) { s_logger.debug("Failed to create object: " + data.getObjectType() + ": " + e.toString()); @@ -821,6 +885,330 @@ public class XenServerStorageResource { return new CopyCmdAnswer("unsupported protocol"); } + boolean swiftUpload(Connection conn, SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI, int wait) { + String result = null; + try { + result = hypervisorResource.callHostPluginAsync(conn, "swiftxen", "swift", wait, + "op", "upload", "url", swift.getUrl(), "account", swift.getAccount(), + "username", swift.getUserName(), "key", swift.getKey(), "container", container, + "ldir", ldir, "lfilename", lfilename, "isISCSI", isISCSI.toString()); + if( result != null && result.equals("true")) { + return true; + } + } catch (Exception e) { + s_logger.warn("swift upload failed due to " + e.toString(), e); + } + return false; + } + + protected String deleteSnapshotBackup(Connection conn, String path, String secondaryStorageMountPath, String backupUUID) { + + // If anybody modifies the formatting below again, I'll skin them + String result = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "deleteSnapshotBackup", "backupUUID", backupUUID, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath); + + return result; + } + + public void swiftBackupSnapshot(Connection conn, SwiftTO swift, String srUuid, String snapshotUuid, String container, Boolean isISCSI, int wait) { + String lfilename; + String ldir; + if ( isISCSI ) { + ldir = "/dev/VG_XenStorage-" + srUuid; + lfilename = "VHD-" + snapshotUuid; + } else { + ldir = "/var/run/sr-mount/" + srUuid; + lfilename = snapshotUuid + ".vhd"; + } + swiftUpload(conn, swift, container, ldir, lfilename, isISCSI, wait); + } + + private static List serializeProperties(final Object object, + final Class propertySet) { + + assert object != null; + assert propertySet != null; + assert propertySet.isAssignableFrom(object.getClass()); + + try { + + final BeanInfo beanInfo = Introspector.getBeanInfo(propertySet); + final PropertyDescriptor[] descriptors = beanInfo + .getPropertyDescriptors(); + + final List serializedProperties = new ArrayList(); + for (final PropertyDescriptor descriptor : descriptors) { + + serializedProperties.add(descriptor.getName()); + final Object value = descriptor.getReadMethod().invoke(object); + serializedProperties.add(value != null ? value.toString() + : "null"); + + } + + return Collections.unmodifiableList(serializedProperties); + + } catch (IntrospectionException e) { + s_logger.warn( + "Ignored IntrospectionException when serializing class " + + object.getClass().getCanonicalName(), e); + } catch (IllegalArgumentException e) { + s_logger.warn( + "Ignored IllegalArgumentException when serializing class " + + object.getClass().getCanonicalName(), e); + } catch (IllegalAccessException e) { + s_logger.warn( + "Ignored IllegalAccessException when serializing class " + + object.getClass().getCanonicalName(), e); + } catch (InvocationTargetException e) { + s_logger.warn( + "Ignored InvocationTargetException when serializing class " + + object.getClass().getCanonicalName(), e); + } + + return Collections.emptyList(); + + } + + private boolean backupSnapshotToS3(final Connection connection, + final S3TO s3, final String srUuid, final String snapshotUuid, + final Boolean iSCSIFlag, final int wait) { + + final String filename = iSCSIFlag ? "VHD-" + snapshotUuid + : snapshotUuid + ".vhd"; + final String dir = (iSCSIFlag ? "/dev/VG_XenStorage-" + : "/var/run/sr-mount/") + srUuid; + final String key = StringUtils.join("/", "snapshots", snapshotUuid); + + try { + + final List parameters = new ArrayList( + serializeProperties(s3, S3Utils.ClientOptions.class)); + parameters.addAll(Arrays.asList("operation", "put", "directory", + dir, "filename", filename, "iSCSIFlag", + iSCSIFlag.toString(), "key", key)); + final String result = hypervisorResource.callHostPluginAsync(connection, "s3xen", + "s3", wait, + parameters.toArray(new String[parameters.size()])); + + if (result != null && result.equals("true")) { + return true; + } + + } catch (Exception e) { + s_logger.error(String.format( + "S3 upload failed of snapshot %1$s due to %2$s.", + snapshotUuid, e.toString()), e); + } + + return false; + + } + + protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String path, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) { + String backupSnapshotUuid = null; + + if (prevBackupUuid == null) { + prevBackupUuid = ""; + } + + // Each argument is put in a separate line for readability. + // Using more lines does not harm the environment. + String backupUuid = UUID.randomUUID().toString(); + String results = hypervisorResource.callHostPluginAsync(conn, "vmopsSnapshot", "backupSnapshot", wait, + "primaryStorageSRUuid", primaryStorageSRUuid, "path", path, "secondaryStorageMountPath", secondaryStorageMountPath, + "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString()); + String errMsg = null; + if (results == null || results.isEmpty()) { + errMsg = "Could not copy backupUuid: " + backupSnapshotUuid + + " from primary storage " + primaryStorageSRUuid + " to secondary storage " + + secondaryStorageMountPath + " due to null"; + } else { + + String[] tmp = results.split("#"); + String status = tmp[0]; + backupSnapshotUuid = tmp[1]; + // status == "1" if and only if backupSnapshotUuid != null + // So we don't rely on status value but return backupSnapshotUuid as an + // indicator of success. + if (status != null && status.equalsIgnoreCase("1") && backupSnapshotUuid != null) { + s_logger.debug("Successfully copied backupUuid: " + backupSnapshotUuid + + " to secondary storage"); + return backupSnapshotUuid; + } else { + errMsg = "Could not copy backupUuid: " + backupSnapshotUuid + + " from primary storage " + primaryStorageSRUuid + " to secondary storage " + + secondaryStorageMountPath + " due to " + tmp[1]; + } + } + String source = backupUuid + ".vhd"; + hypervisorResource.killCopyProcess(conn, source); + s_logger.warn(errMsg); + return null; + + } + + private boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, String volumeUuid, String avoidSnapshotUuid){ + try { + VDI volume = getVDIbyUuid(conn, volumeUuid); + if (volume == null) { + throw new InternalErrorException("Could not destroy snapshot on volume " + volumeUuid + " due to can not find it"); + } + Set snapshots = volume.getSnapshots(conn); + for( VDI snapshot : snapshots ) { + try { + if(! snapshot.getUuid(conn).equals(avoidSnapshotUuid)) { + snapshot.destroy(conn); + } + } catch (Exception e) { + String msg = "Destroying snapshot: " + snapshot+ " on primary storage failed due to " + e.toString(); + s_logger.warn(msg, e); + } + } + s_logger.debug("Successfully destroyed snapshot on volume: " + volumeUuid + " execept this current snapshot "+ avoidSnapshotUuid ); + return true; + } catch (XenAPIException e) { + String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot "+ avoidSnapshotUuid + " failed due to " + e.toString(); + s_logger.error(msg, e); + } catch (Exception e) { + String msg = "Destroying snapshot on volume: " + volumeUuid + " execept this current snapshot "+ avoidSnapshotUuid + " failed due to " + e.toString(); + s_logger.warn(msg, e); + } + + return false; + } + + protected Answer backupSnasphot(DataTO srcData, DataTO destData, DataTO cacheData, int wait) { + Connection conn = hypervisorResource.getConnection(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore(); + String primaryStorageNameLabel = primaryStore.getUuid(); + String secondaryStorageUrl = null; + NfsTO cacheStore = null; + String destPath = null; + if (cacheData != null) { + cacheStore = (NfsTO)cacheData.getDataStore(); + secondaryStorageUrl = cacheStore.getUrl(); + destPath = cacheData.getPath(); + } else { + cacheStore = (NfsTO)destData.getDataStore(); + secondaryStorageUrl = cacheStore.getUrl(); + destPath = destData.getPath(); + } + + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData; + SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData; + String snapshotUuid = snapshotTO.getPath(); + + String prevBackupUuid = snapshotOnImage.getParentSnapshotPath(); + String prevSnapshotUuid = snapshotTO.getParentSnapshotPath(); + + // By default assume failure + String details = null; + String snapshotBackupUuid = null; + boolean fullbackup = true; + try { + SR primaryStorageSR = hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); + if (primaryStorageSR == null) { + throw new InternalErrorException("Could not backup snapshot because the primary Storage SR could not be created from the name label: " + primaryStorageNameLabel); + } + String psUuid = primaryStorageSR.getUuid(conn); + Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn)); + + VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); + String snapshotPaUuid = null; + if ( prevBackupUuid != null ) { + try { + snapshotPaUuid = getVhdParent(conn, psUuid, snapshotUuid, isISCSI); + if( snapshotPaUuid != null ) { + String snashotPaPaPaUuid = getVhdParent(conn, psUuid, snapshotPaUuid, isISCSI); + String prevSnashotPaUuid = getVhdParent(conn, psUuid, prevSnapshotUuid, isISCSI); + if (snashotPaPaPaUuid != null && prevSnashotPaUuid!= null && prevSnashotPaUuid.equals(snashotPaPaPaUuid)) { + fullbackup = false; + } + } + } catch (Exception e) { + } + } + + URI uri = new URI(secondaryStorageUrl); + String secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); + DataStoreTO destStore = destData.getDataStore(); + String folder = destPath; + if (fullbackup) { + // the first snapshot is always a full snapshot + + if( !hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder)) { + details = " Filed to create folder " + folder + " in secondary storage"; + s_logger.warn(details); + return new CopyCmdAnswer(details); + } + String snapshotMountpoint = secondaryStorageUrl + "/" + folder; + SR snapshotSr = null; + try { + snapshotSr = hypervisorResource.createNfsSRbyURI(conn, new URI(snapshotMountpoint), false); + VDI backedVdi = hypervisorResource.cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait); + snapshotBackupUuid = backedVdi.getUuid(conn); + + if( destStore instanceof SwiftTO) { + try { + hypervisorResource.swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), false, wait); + snapshotBackupUuid = snapshotBackupUuid + ".vhd"; + } finally { + deleteSnapshotBackup(conn, folder, secondaryStorageMountPath, snapshotBackupUuid); + } + } else if (destStore instanceof S3TO) { + try { + backupSnapshotToS3(conn, (S3TO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, isISCSI, wait); + snapshotBackupUuid = snapshotBackupUuid + ".vhd"; + } finally { + deleteSnapshotBackup(conn, folder, secondaryStorageMountPath, snapshotBackupUuid); + } + } + + } finally { + if( snapshotSr != null) { + hypervisorResource.removeSR(conn, snapshotSr); + } + } + } else { + String primaryStorageSRUuid = primaryStorageSR.getUuid(conn); + if( destStore instanceof SwiftTO ) { + swiftBackupSnapshot(conn, (SwiftTO)destStore, primaryStorageSRUuid, snapshotPaUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), isISCSI, wait); + if ( isISCSI ) { + snapshotBackupUuid = "VHD-" + snapshotPaUuid; + } else { + snapshotBackupUuid = snapshotPaUuid + ".vhd"; + } + + } else if (destStore instanceof S3TO ) { + backupSnapshotToS3(conn, (S3TO)destStore, primaryStorageSRUuid, snapshotPaUuid, isISCSI, wait); + } else { + snapshotBackupUuid = backupSnapshot(conn, primaryStorageSRUuid, folder + File.separator + UUID.nameUUIDFromBytes(secondaryStorageMountPath.getBytes()) + , secondaryStorageMountPath, snapshotUuid, prevBackupUuid, isISCSI, wait); + + } + } + String volumeUuid = snapshotTO.getVolume().getPath(); + destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid); + + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + newSnapshot.setPath(snapshotBackupUuid); + if (fullbackup) { + newSnapshot.setParentSnapshotPath(null); + } else { + newSnapshot.setParentSnapshotPath(prevBackupUuid); + } + return new CopyCmdAnswer(newSnapshot); + } catch (XenAPIException e) { + details = "BackupSnapshot Failed due to " + e.toString(); + s_logger.warn(details, e); + } catch (Exception e) { + details = "BackupSnapshot Failed due to " + e.getMessage(); + s_logger.warn(details, e); + } + + return new CopyCmdAnswer(details); + } + protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); @@ -838,6 +1226,9 @@ public class XenServerStorageResource { return copyVolumeFromImageCacheToPrimary(srcData, destData, cmd.getWait()); } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { return copyVolumeFromPrimaryToSecondary(srcData, destData, cmd.getWait()); + } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) { + DataTO cacheData = cmd.getCacheTO(); + return backupSnasphot(srcData, destData, cacheData, cmd.getWait()); } return new Answer(cmd, false, "not implemented yet"); diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 5e82a7eaec1..93d37ded506 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -36,6 +36,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -193,24 +194,17 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri AsyncCompletionCallback callback) { CreateCmdResult result = null; try { - VolumeInfo volume = snapshot.getBaseVolume(); - String vmName = this.volumeMgr.getVmNameOnVolume(volume); - SnapshotVO preSnapshotVO = this.snapshotMgr.getParentSnapshot(volume, snapshot); - String parentSnapshotPath = null; - if (preSnapshotVO != null) { - parentSnapshotPath = preSnapshotVO.getPath(); + DataTO snapshotTO = snapshot.getTO(); + + CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO); + Answer answer = storageMgr.sendToPool((StoragePool)snapshot.getDataStore(), null, cmd); + + result = new CreateCmdResult(null, answer); + if (answer != null && !answer.getResult()) { + result.setResult(answer.getDetails()); } - StoragePool srcPool = (StoragePool)volume.getDataStore(); - ManageSnapshotCommand cmd = new ManageSnapshotCommand(snapshot.getId(), volume.getPath(), srcPool, parentSnapshotPath, snapshot.getName(), vmName); - - ManageSnapshotAnswer answer = (ManageSnapshotAnswer) this.snapshotMgr.sendToPool(volume, cmd); - - if ((answer != null) && answer.getResult()) { - result = new CreateCmdResult(answer.getSnapshotPath(), null); - } else { - result = new CreateCmdResult(null, null); - } + callback.complete(result); } catch (Exception e) { s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); result = new CreateCmdResult(null, null); diff --git a/server/src/com/cloud/storage/CreateSnapshotPayload.java b/server/src/com/cloud/storage/CreateSnapshotPayload.java index cafe46c8814..2eec00d39c3 100644 --- a/server/src/com/cloud/storage/CreateSnapshotPayload.java +++ b/server/src/com/cloud/storage/CreateSnapshotPayload.java @@ -1,7 +1,11 @@ package com.cloud.storage; +import com.cloud.user.Account; + public class CreateSnapshotPayload { private Long snapshotPolicyId; + private Long snapshotId; + private Account account; public Long getSnapshotPolicyId() { return snapshotPolicyId; @@ -11,4 +15,20 @@ public class CreateSnapshotPayload { this.snapshotPolicyId = snapshotPolicyId; } + public Long getSnapshotId() { + return snapshotId; + } + + public void setSnapshotId(Long snapshotId) { + this.snapshotId = snapshotId; + } + + public Account getAccount() { + return account; + } + + public void setAccount(Account account) { + this.account = account; + } + } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 3177a591728..23e329558c7 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -133,6 +133,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; +import com.cloud.storage.snapshot.SnapshotApiService; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; import com.cloud.tags.dao.ResourceTagDao; @@ -307,6 +308,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { TemplateDataFactory tmplFactory; @Inject SnapshotDataFactory snapshotFactory; + @Inject + SnapshotApiService snapshotMgr; private int _copyvolumewait; @Inject protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; @@ -526,7 +529,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { VolumeInfo vol = this.volFactory.getVolume(volume.getId()); DataStore store = this.dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); - SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId()); + SnapshotInfo snapInfo = this.snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Image); AsyncCallFuture future = this.volService.createVolumeFromSnapshot(vol, store, snapInfo); try { VolumeApiResult result = future.get(); @@ -2470,8 +2473,26 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @Override - public Snapshot takeSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException { - Account caller = UserContext.current().getCaller(); + public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account) throws ResourceAllocationException { + VolumeInfo volume = this.volFactory.getVolume(volumeId); + if (volume == null) { + throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); + } + + if (volume.getState() != Volume.State.Ready) { + throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); + } + + CreateSnapshotPayload payload = new CreateSnapshotPayload(); + payload.setSnapshotId(snapshotId); + payload.setSnapshotPolicyId(policyId); + payload.setAccount(account); + return this.volService.takeSnapshot(volume); + } + + @Override + public Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException { + Account caller = UserContext.current().getCaller(); VolumeInfo volume = this.volFactory.getVolume(volumeId); if (volume == null) { @@ -2502,10 +2523,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it"); } - CreateSnapshotPayload payload = new CreateSnapshotPayload(); - payload.setSnapshotPolicyId(policyId); - return this.volService.takeSnapshot(volume); - + return this.snapshotMgr.allocSnapshot(volumeId, policyId); } } diff --git a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java index 24d4c653aeb..a3493890a59 100644 --- a/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/server/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -151,7 +151,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements VolumeIdVersionSearch.and("volumeId", VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdVersionSearch.and("version", VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ); VolumeIdVersionSearch.done(); - +/* ParentIdSearch = createSearchBuilder(); ParentIdSearch.and("prevSnapshotId", ParentIdSearch.entity().getPrevSnapshotId(), SearchCriteria.Op.EQ); ParentIdSearch.done(); @@ -159,7 +159,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements backupUuidSearch = createSearchBuilder(); backupUuidSearch.and("backupUuid", backupUuidSearch.entity().getBackupSnapshotId(), SearchCriteria.Op.EQ); backupUuidSearch.done(); - +*/ AccountIdSearch = createSearchBuilder(); AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.done(); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index 983b50c3e65..d6e0af66da2 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -56,10 +56,6 @@ public interface SnapshotManager { * The account which is to be deleted. */ boolean deleteSnapshotDirsForAccount(long accountId); - - void downloadSnapshotsFromSwift(SnapshotVO ss); - - void downloadSnapshotsFromS3(SnapshotVO snapshot); String getSecondaryStorageURL(SnapshotVO snapshot); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index c18ffa87092..572bcab691c 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -349,8 +349,10 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, return this.snapshotSrv.backupSnapshot(snapshot); } + /* @Override public void downloadSnapshotsFromSwift(SnapshotVO ss) { + long volumeId = ss.getVolumeId(); VolumeVO volume = _volsDao.findById(volumeId); Long dcId = volume.getDataCenterId(); @@ -432,7 +434,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, e); } - } + }*/ @Override public SnapshotVO getParentSnapshot(VolumeInfo volume) { @@ -974,72 +976,44 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } @Override public SnapshotInfo takeSnapshot(VolumeInfo volume) throws ResourceAllocationException { - Account caller = UserContext.current().getCaller(); - - supportedByHypervisor(volume); - CreateSnapshotPayload snapInfo = (CreateSnapshotPayload)volume.getpayload(); - Long policyId = snapInfo.getSnapshotPolicyId(); - // Verify permissions - _accountMgr.checkAccess(caller, null, true, volume); - Type snapshotType = getSnapshotType(policyId); - Account owner = _accountMgr.getAccount(volume.getAccountId()); - - try{ - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot); - if (backup) { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.secondary_storage, new Long(volume.getSize())); - } else { - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, new Long(volume.getSize())); - } - } catch (ResourceAllocationException e) { - if (snapshotType != Type.MANUAL){ - String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots"; - s_logger.warn(msg); - _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, - "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit"); - } - throw e; - } - - // Determine the name for this snapshot - // Snapshot Name: VMInstancename + volumeName + timeString - String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT); - - VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId()); - String vmDisplayName = "detached"; - if (vmInstance != null) { - vmDisplayName = vmInstance.getHostName(); - } - String snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString; - - HypervisorType hypervisorType = volume.getHypervisorType(); - SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName, - (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType); - - SnapshotVO snapshot = _snapshotDao.persist(snapshotVO); - if (snapshot == null) { - throw new CloudRuntimeException("Failed to create snapshot for volume: " + volume.getId()); - } - if (backup) { - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, - new Long(volume.getSize())); - } else { - _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, - new Long(volume.getSize())); - } - SnapshotInfo snap = this.snapshotFactory.getSnapshot(snapshot.getId(), volume.getDataStore()); + CreateSnapshotPayload payload = (CreateSnapshotPayload)volume.getpayload(); + Long snapshotId = payload.getSnapshotId(); + Account snapshotOwner = payload.getAccount(); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotId, volume.getDataStore()); boolean processed = false; - for (SnapshotStrategy strategy : snapshotStrategies) { - if (strategy.canHandle(snap)) { - processed = true; - snap = strategy.takeSnapshot(snap); - break; - } + + try { + for (SnapshotStrategy strategy : snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + processed = true; + snapshot = strategy.takeSnapshot(snapshot); + break; + } + } + if (!processed) { + throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId); + } + postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId()); + + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), + snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, + volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid()); + + + _resourceLimitMgr.incrementResourceCount(snapshotOwner.getId(), ResourceType.snapshot); + + } catch(Exception e) { + s_logger.debug("Failed to create snapshot", e); + if (backup) { + _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.secondary_storage, + new Long(volume.getSize())); + } else { + _resourceLimitMgr.decrementResourceCount(snapshotOwner.getId(), ResourceType.primary_storage, + new Long(volume.getSize())); + } + throw new CloudRuntimeException("Failed to create snapshot", e); } - if (!processed) { - throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshot.getId()); - } - return snap; + return snapshot; } @Override @@ -1128,4 +1102,61 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } return true; } + + @Override + public Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException { + Account caller = UserContext.current().getCaller(); + VolumeInfo volume = this.volFactory.getVolume(volumeId); + supportedByHypervisor(volume); + + // Verify permissions + _accountMgr.checkAccess(caller, null, true, volume); + Type snapshotType = getSnapshotType(policyId); + Account owner = _accountMgr.getAccount(volume.getAccountId()); + + try{ + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot); + if (backup) { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.secondary_storage, new Long(volume.getSize())); + } else { + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, new Long(volume.getSize())); + } + } catch (ResourceAllocationException e) { + if (snapshotType != Type.MANUAL){ + String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots"; + s_logger.warn(msg); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, + "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit"); + } + throw e; + } + + // Determine the name for this snapshot + // Snapshot Name: VMInstancename + volumeName + timeString + String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT); + + VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId()); + String vmDisplayName = "detached"; + if (vmInstance != null) { + vmDisplayName = vmInstance.getHostName(); + } + String snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString; + + HypervisorType hypervisorType = volume.getHypervisorType(); + SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName, + (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType); + + SnapshotVO snapshot = _snapshotDao.persist(snapshotVO); + if (snapshot == null) { + throw new CloudRuntimeException("Failed to create snapshot for volume: " + volume.getId()); + } + if (backup) { + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, + new Long(volume.getSize())); + } else { + _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, + new Long(volume.getSize())); + } + return snapshot; + } } diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index de69c12376a..fbac9b40892 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1355,7 +1355,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } AsyncCallFuture future = null; if (snapshotId != null) { - SnapshotInfo snapInfo = this._snapshotFactory.getSnapshot(snapshotId); + SnapshotInfo snapInfo = this._snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image); future = this._tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); } else if (volumeId != null) { volume = _volumeDao.findById(volumeId); From 99dcb23b1c8bd3134d8b0bbbe9aa7c6acc44ada2 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 29 Apr 2013 19:37:47 -0700 Subject: [PATCH 076/303] fix build --- .../driver/CloudStackImageStoreDriverImpl.java | 6 +++--- .../datastore/driver/S3ImageStoreDriverImpl.java | 7 ++----- .../datastore/driver/SwiftImageStoreDriverImpl.java | 7 ++----- .../driver/SamplePrimaryDataStoreDriverImpl.java | 10 +++++----- .../org/apache/cloudstack/storage/test/VolumeTest.java | 2 +- 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 277cbf9f276..8e1511c0b9e 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -335,12 +335,12 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } try { - String secondaryStoragePoolUrl = secStore.getUri(); + /*String secondaryStoragePoolUrl = secStore.getUri(); Long dcId = snapshot.getDataCenterId(); Long accountId = snapshot.getAccountId(); Long volumeId = snapshot.getVolumeId(); - String backupOfSnapshot = snapshotObj.getBackupSnapshotId(); + String backupOfSnapshot = snapshotObj; if (backupOfSnapshot == null) { callback.complete(result); return; @@ -357,7 +357,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { snapshotDao.update(snapshotObj.getId(), snapshot); } else if (answer != null) { result.setResult(answer.getDetails()); - } + }*/ } catch (Exception e) { s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); result.setResult(e.toString()); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index f3aefe06a0d..384e7f010e3 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -298,7 +298,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { Long accountId = snapshot.getAccountId(); Long volumeId = snapshot.getVolumeId(); - String backupOfSnapshot = snapshotObj.getBackupSnapshotId(); + String backupOfSnapshot = snapshotObj.getPath(); if (backupOfSnapshot == null) { callback.complete(result); return; @@ -310,10 +310,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); - if ((answer != null) && answer.getResult()) { - snapshot.setBackupSnapshotId(null); - snapshotDao.update(snapshotObj.getId(), snapshot); - } else if (answer != null) { + if (answer != null) { result.setResult(answer.getDetails()); } } catch (Exception e) { diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index e8009fc0239..aa0f3755dd4 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -292,7 +292,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { Long accountId = snapshot.getAccountId(); Long volumeId = snapshot.getVolumeId(); - String backupOfSnapshot = snapshotObj.getBackupSnapshotId(); + String backupOfSnapshot = snapshotObj.getPath(); if (backupOfSnapshot == null) { callback.complete(result); return; @@ -304,10 +304,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); - if ((answer != null) && answer.getResult()) { - snapshot.setBackupSnapshotId(null); - snapshotDao.update(snapshotObj.getId(), snapshot); - } else if (answer != null) { + if (answer != null) { result.setResult(answer.getDetails()); } } catch (Exception e) { diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index 73dfa8052f3..a9226c7da39 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -90,7 +90,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver } public Void createAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { - CreateCmdResult result = null; + /*CreateCmdResult result = null; CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult()) { result = new CreateCmdResult(volAnswer.getPath(), volAnswer); @@ -99,7 +99,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver result.setResult(volAnswer.getDetails()); } - context.getParentCallback().complete(result); + context.getParentCallback().complete(result);*/ return null; } @@ -177,7 +177,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver public void createAsync(DataObject vol, AsyncCompletionCallback callback) { EndPoint ep = selector.select(vol); - CreateObjectCommand createCmd = new CreateObjectCommand(vol.getUri()); + CreateObjectCommand createCmd = new CreateObjectCommand(null); CreateVolumeContext context = new CreateVolumeContext(callback, vol); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); @@ -197,10 +197,10 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver if (obj.getPath() == null) { //create an obj EndPoint newEp = selector.select(object); - CreateObjectCommand createCmd = new CreateObjectCommand(uri); + CreateObjectCommand createCmd = new CreateObjectCommand(null); CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd); if (answer.getResult()) { - dataObjMgr.update(object, answer.getPath(), answer.getSize()); + //dataObjMgr.update(object, answer.getPath(), answer.getSize()); } else { s_logger.debug("failed to create object" + answer.getDetails()); throw new CloudRuntimeException("failed to create object" + answer.getDetails()); diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java index 91bc7ea0117..5bc929d3efc 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -109,7 +109,7 @@ public class VolumeTest { results.add(host); Mockito.when(hostDao.listAll()).thenReturn(results); Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); - CreateObjectAnswer createVolumeFromImageAnswer = new CreateObjectAnswer(null,UUID.randomUUID().toString(), null); + //CreateObjectAnswer createVolumeFromImageAnswer = new CreateObjectAnswer(null,UUID.randomUUID().toString(), null); From 91c586caa612a6f5838b0153ccb35c9a1106e4b4 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 30 Apr 2013 10:13:30 -0700 Subject: [PATCH 077/303] Fix MS startup exception. --- client/pom.xml | 7 +++++- client/tomcatconf/applicationContext.xml.in | 1 - setup/db/db/schema-410to420.sql | 24 ++++++++++----------- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index 39f1cb0d1a6..aba46cec031 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -189,6 +189,11 @@ cloud-engine-storage ${project.version} + + org.apache.cloudstack + cloud-engine-storage-cache + ${project.version} + org.apache.cloudstack cloud-engine-storage-backup @@ -201,7 +206,7 @@ org.apache.cloudstack - cloud-engine-storage-imagemotion + cloud-engine-storage-datamotion ${project.version} diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 7bbcf0959a8..9361e03476d 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -213,7 +213,6 @@ - diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index f54cf573fa7..379c3fdf8d1 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -30,12 +30,12 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'Agent ALTER TABLE `cloud`.`load_balancer_vm_map` ADD state VARCHAR(40) NULL COMMENT 'service status updated by LB healthcheck manager'; alter table storage_pool change storage_provider_id storage_provider_name varchar(255); -alter table template_host_ref add state varchar(255); -alter table template_host_ref add update_count bigint unsigned; -alter table template_host_ref add updated datetime; -alter table volume_host_ref add state varchar(255); -alter table volume_host_ref add update_count bigint unsigned; -alter table volume_host_ref add updated datetime; +-- alter table template_host_ref add state varchar(255); +-- alter table template_host_ref add update_count bigint unsigned; +-- alter table template_host_ref add updated datetime; +-- alter table volume_host_ref add state varchar(255); +-- alter table volume_host_ref add update_count bigint unsigned; +-- alter table volume_host_ref add updated datetime; alter table template_spool_ref add updated datetime; CREATE TABLE `cloud`.`object_datastore_ref` ( `id` bigint unsigned NOT NULL auto_increment, @@ -652,12 +652,12 @@ CREATE VIEW `cloud`.`volume_view` AS vm_instance.state vm_state, vm_instance.vm_type, user_vm.display_name vm_display_name, - volume_host_ref.size volume_host_size, - volume_host_ref.created volume_host_created, - volume_host_ref.format, - volume_host_ref.download_pct, - volume_host_ref.download_state, - volume_host_ref.error_str, + volume_store_ref.size volume_host_size, + volume_store_ref.created volume_host_created, + volume_store_ref.format, + volume_store_ref.download_pct, + volume_store_ref.download_state, + volume_store_ref.error_str, disk_offering.id disk_offering_id, disk_offering.uuid disk_offering_uuid, disk_offering.name disk_offering_name, From 7d2565c491502a86f6ee65c6f1d68dde9b2ce4ff Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 30 Apr 2013 10:43:21 -0700 Subject: [PATCH 078/303] Fix applicationContext.xml.in for some MS startup issues. --- client/tomcatconf/applicationContext.xml.in | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 9361e03476d..9dcee8bb0ed 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -228,7 +228,8 @@ - + + @@ -717,7 +718,8 @@ - + + @@ -741,7 +743,7 @@ - + From bbd5d132138ac26283da1c30bf11825354227907 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 30 Apr 2013 11:31:45 -0700 Subject: [PATCH 079/303] Fix bugs in refactored listTemplates and listIsos API. --- client/tomcatconf/applicationContext.xml.in | 1 + .../cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java | 4 ++-- server/src/com/cloud/api/query/QueryManagerImpl.java | 4 ++-- server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java | 2 +- server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java | 2 +- setup/db/db/schema-410to420.sql | 2 ++ 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 9dcee8bb0ed..194b763879c 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -720,6 +720,7 @@ + diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 11babcbabf3..05a0da081c8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -65,13 +65,13 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = _templateJoinDao.createSearchCriteria(); // add criteria for project or not @@ -2577,7 +2577,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } // add hypervisor criteria - if ( !hypers.isEmpty()){ + if ( hypers != null && !hypers.isEmpty()){ String[] relatedHypers = new String[hypers.size()]; for (int i = 0; i < hypers.size(); i++){ relatedHypers[i] = hypers.get(i).toString(); diff --git a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java index 72446f493bb..7810ffc16ae 100644 --- a/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/ImageStoreJoinDaoImpl.java @@ -58,7 +58,7 @@ public class ImageStoreJoinDaoImpl extends GenericDaoBase Date: Tue, 30 Apr 2013 17:42:48 -0700 Subject: [PATCH 080/303] Bugfix to make deployDataCenter.py work. --- .../engine/subsystem/api/storage/ImageStoreProvider.java | 2 ++ .../storage/datastore/db/SnapshotDataStoreVO.java | 9 +++++++-- .../storage/datastore/db/VolumeDataStoreVO.java | 5 +++++ .../storage/datastore/ObjectInDataStoreManagerImpl.java | 5 +++++ .../storage/image/datastore/ImageStoreHelper.java | 2 +- .../lifecycle/CloudStackImageStoreLifeCycleImpl.java | 4 ++++ .../provider/CloudStackImageStoreProviderImpl.java | 5 +++++ .../datastore/lifecycle/S3ImageStoreLifeCycleImpl.java | 3 +++ .../datastore/provider/S3ImageStoreProviderImpl.java | 5 +++++ .../datastore/provider/SampleImageStoreProviderImpl.java | 5 +++++ .../lifecycle/SwiftImageStoreLifeCycleImpl.java | 6 +++++- .../datastore/provider/SwiftImageStoreProviderImpl.java | 5 +++++ server/src/com/cloud/storage/StorageManagerImpl.java | 6 ++++-- .../com/cloud/storage/download/DownloadMonitorImpl.java | 7 ++++++- .../storage/secondary/SecondaryStorageManagerImpl.java | 2 +- setup/db/db/schema-410to420.sql | 8 ++++++++ tools/marvin/marvin/configGenerator.py | 3 +++ tools/marvin/marvin/deployDataCenter.py | 6 ++++-- 18 files changed, 78 insertions(+), 10 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index 9b4b937b18a..0f3f05b3ee7 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java @@ -24,4 +24,6 @@ import com.cloud.storage.ScopeType; public interface ImageStoreProvider extends DataStoreProvider { public boolean isScopeSupported(ScopeType scope); + + public boolean needDownloadSysTemplate(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index af478ab92ba..0085086e437 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -51,7 +51,7 @@ public class SnapshotDataStoreVO implements StateObject details = (Map)dsInfos.get("details"); s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); @@ -115,6 +117,8 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { imageStoreParameters.put("protocol", uri.getScheme().toLowerCase()); imageStoreParameters.put("scope", ScopeType.ZONE); // default cloudstack provider only supports zone-wide image store imageStoreParameters.put("providerName", providerName); + imageStoreParameters.put("role", role); + ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters, details); return imageStoreMgr.getImageStore(ids.getId()); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index fdeba4d7c73..953a078464b 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -94,5 +94,10 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { return false; } + @Override + public boolean needDownloadSysTemplate() { + return false; + } + } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java index c3843560296..05c9e37aca4 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -47,6 +47,7 @@ import com.cloud.resource.Discoverer; import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; import com.cloud.resource.ServerResource; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.s3.S3Manager; import com.cloud.utils.UriUtils; @@ -85,6 +86,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { String url = (String) dsInfos.get("url"); String providerName = (String)dsInfos.get("providerName"); ScopeType scope = (ScopeType)dsInfos.get("scope"); + DataStoreRole role =(DataStoreRole) dsInfos.get("role"); Map details = (Map)dsInfos.get("details"); s_logger.info("Trying to add a S3 store in data center " + dcId); @@ -113,6 +115,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { imageStoreParameters.put("scope", ScopeType.REGION); } imageStoreParameters.put("providerName", providerName); + imageStoreParameters.put("role", role); ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters, details); return imageStoreMgr.getImageStore(ids.getId()); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java index ba27d617838..174e2dbc482 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java @@ -94,5 +94,10 @@ public class S3ImageStoreProviderImpl implements ImageStoreProvider { return false; } + @Override + public boolean needDownloadSysTemplate() { + return true; + } + } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index eadb01df8f7..4b96da7d023 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -88,5 +88,10 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { return false; } + @Override + public boolean needDownloadSysTemplate() { + return false; + } + } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java index 799d4e0812c..20e0939b9fe 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -46,6 +46,7 @@ import com.cloud.resource.Discoverer; import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; import com.cloud.resource.ServerResource; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.utils.UriUtils; @@ -81,6 +82,8 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { String url = (String) dsInfos.get("url"); ScopeType scope = (ScopeType)dsInfos.get("scope"); String providerName = (String)dsInfos.get("providerName"); + DataStoreRole role =(DataStoreRole) dsInfos.get("role"); + Map details = (Map)dsInfos.get("details"); s_logger.info("Trying to add a swift store at " + url + " in data center " + dcId); @@ -97,8 +100,9 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { imageStoreParameters.put("scope", ScopeType.REGION); } imageStoreParameters.put("providerName", providerName); + imageStoreParameters.put("role", role); - ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters); + ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters, details); return imageStoreMgr.getImageStore(ids.getId()); } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java index 09f09c4ef98..2ba2e9d7f3c 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java @@ -96,5 +96,10 @@ public class SwiftImageStoreProviderImpl implements ImageStoreProvider { return false; } + @Override + public boolean needDownloadSysTemplate() { + return true; + } + } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 05b22576c7a..2eb93709a7f 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1913,8 +1913,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new CloudRuntimeException("Failed to add data store", e); } - // trigger system vm template download - this._imageSrv.downloadBootstrapSysTemplate(store); + if (((ImageStoreProvider) storeProvider).needDownloadSysTemplate()) { + // trigger system vm template download + this._imageSrv.downloadBootstrapSysTemplate(store); + } return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 30549cf5bb1..e37a04d0740 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -74,6 +74,7 @@ import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; +import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.JoinBuilder; @@ -160,7 +161,9 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor _copyAuthPasswd = configs.get("secstorage.copy.password"); - _agentMgr.registerForHostEvents(new DownloadListener(this), true, false, false); + DownloadListener dl = new DownloadListener(this); + ComponentContext.inject(dl); + _agentMgr.registerForHostEvents(dl, true, false, false); ReadyTemplateStatesSearch = _vmTemplateStoreDao.createSearchBuilder(); ReadyTemplateStatesSearch.and("state", ReadyTemplateStatesSearch.entity().getState(), SearchCriteria.Op.EQ); @@ -229,6 +232,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor } DownloadListener dl = new DownloadListener(ep, store, template, _timer, this, dcmd, callback); + ComponentContext.inject(dl); // initialize those auto-wired field in download listener. if (downloadJobExists) { // due to handling existing download job issues, we still keep // downloadState in template_store_ref to avoid big change in @@ -298,6 +302,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor return; } DownloadListener dl = new DownloadListener(ep, store, volume, _timer, this, dcmd, callback); + ComponentContext.inject(dl); // auto-wired those injected fields in DownloadListener if (downloadJobExists) { dl.setCurrState(volumeHost.getDownloadState()); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index e6a41e74a2f..c4fd848f9f4 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -1347,7 +1347,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } } */ - return host; + return null; // no need to handle this event anymore since secondary storage is not in host table anymore. } @Override diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 9d9016e6848..9c492b6c500 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -76,6 +76,7 @@ CREATE TABLE `cloud`.`image_store` ( `url` varchar(255) COMMENT 'url for image data store', `data_center_id` bigint unsigned COMMENT 'datacenter id of data store', `scope` varchar(255) COMMENT 'scope of data store', + `role` varchar(255) COMMENT 'role of data store', `uuid` varchar(255) COMMENT 'uuid of data store', `parent` varchar(255) COMMENT 'parent path for the storage server', `created` datetime COMMENT 'date the image store first signed on', @@ -135,6 +136,8 @@ CREATE TABLE `cloud`.`template_store_ref` ( `state` varchar(255) NOT NULL, `destroyed` tinyint(1) COMMENT 'indicates whether the template_store entry was destroyed by the user or not', `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', + `update_count` bigint unsigned, + `updated` datetime, PRIMARY KEY (`id`), -- CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_template_store_ref__store_id`(`store_id`), @@ -160,11 +163,14 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `created` DATETIME NOT NULL, `last_updated` DATETIME, `job_id` varchar(255), + `store_role` varchar(255), `size` bigint unsigned, `physical_size` bigint unsigned DEFAULT 0, `install_path` varchar(255), `state` varchar(255) NOT NULL, `destroyed` tinyint(1) COMMENT 'indicates whether the snapshot_store entry was destroyed by the user or not', + `update_count` bigint unsigned, + `updated` datetime, PRIMARY KEY (`id`), CONSTRAINT `fk_snapshot_store_ref__store_id` FOREIGN KEY `fk_snapshot_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_snapshot_store_ref__store_id`(`store_id`), @@ -192,6 +198,8 @@ CREATE TABLE `cloud`.`volume_store_ref` ( `state` varchar(255) NOT NULL, `format` varchar(32) NOT NULL COMMENT 'format for the volume', `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', + `update_count` bigint unsigned, + `updated` datetime, PRIMARY KEY (`id`), CONSTRAINT `fk_volume_store_ref__store_id` FOREIGN KEY `fk_volume_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_volume_store_ref__store_id`(`store_id`), diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index e2a6a24d69f..8235b095ca1 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -70,6 +70,7 @@ class zone(): self.physical_networks = [] self.pods = [] self.secondaryStorages = [] + class traffictype(): def __init__(self, typ, labeldict=None): @@ -178,6 +179,8 @@ class primaryStorage(): class secondaryStorage(): def __init__(self): self.url = None + self.providerName = None + self.details = None class s3(): def __init__(self): diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index cec920c5ff0..aaf05011dc1 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -138,10 +138,12 @@ class deployDataCenters(): if secondaryStorages is None: return for secondary in secondaryStorages: - secondarycmd = addSecondaryStorage.addSecondaryStorageCmd() + secondarycmd = addImageStore.addImageStoreCmd() secondarycmd.url = secondary.url + secondarycmd.provider = secondary.providerName + """if secondary.provider == "CloudStack ImageStore Provider":""" secondarycmd.zoneid = zoneId - self.apiClient.addSecondaryStorage(secondarycmd) + self.apiClient.addImageStore(secondarycmd) def createnetworks(self, networks, zoneId): if networks is None: From 881165e5d3e6020402979cdd1f0293b014603283 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 30 Apr 2013 17:44:16 -0700 Subject: [PATCH 081/303] Fix devcloud.cfg to work with new addImageStore api. --- tools/devcloud/devcloud.cfg | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg index c41f8bcef58..bf4cc92eed5 100644 --- a/tools/devcloud/devcloud.cfg +++ b/tools/devcloud/devcloud.cfg @@ -83,10 +83,13 @@ "internaldns1": "192.168.56.1", "secondaryStorages": [ { - "url": "nfs://192.168.56.10:/opt/storage/secondary" + "url": "nfs://192.168.56.10:/opt/storage/secondary", + "providerName": "CloudStack ImageStore Provider", + "details": { + } } ] - } + } ], "logger": [ { From 3c6b7c2a016fc9cf25dfae2cd2e74fab33244423 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 1 May 2013 12:10:24 -0700 Subject: [PATCH 082/303] Populate system vm template to template_store_ref in adding an image store. --- .../api/storage/TemplateService.java | 1 + .../storage/datastore/db/ImageStoreVO.java | 4 +- .../datastore/db/TemplateDataStoreVO.java | 20 ++++++++ .../storage/image/TemplateServiceImpl.java | 18 +++++++ .../image/datastore/ImageStoreHelper.java | 1 + .../vmware/manager/VmwareManagerImpl.java | 10 ++-- .../com/cloud/api/query/QueryManagerImpl.java | 4 +- .../com/cloud/storage/StorageManagerImpl.java | 21 +++++--- .../com/cloud/storage/s3/S3ManagerImpl.java | 16 +++--- .../SecondaryStorageManagerImpl.java | 49 +++---------------- .../secondary/SecondaryStorageVmManager.java | 7 --- .../template/HypervisorTemplateAdapter.java | 39 +++++---------- 12 files changed, 94 insertions(+), 96 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index dd017a11327..b0f9f37d85b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -50,4 +50,5 @@ public interface TemplateService { void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId); void handleTemplateSync(DataStore store); void downloadBootstrapSysTemplate(DataStore store); + void addSystemVMTemplatesToSecondary(DataStore store); } 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 676004b0314..8e6c6a88a84 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 @@ -60,7 +60,7 @@ public class ImageStoreVO implements ImageStore { private String providerName; @Column(name = "data_center_id") - private long dcId; + private Long dcId; @Column(name = "scope") @Enumerated(value = EnumType.STRING) @@ -117,7 +117,7 @@ public class ImageStoreVO implements ImageStore { return this.protocol; } - public void setDataCenterId(long dcId) { + public void setDataCenterId(Long dcId) { this.dcId = dcId; } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index 7d645446fba..6347e613e67 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -190,6 +190,26 @@ public class TemplateDataStoreVO implements StateObject rtngTmplts = _templateDao.listAllSystemVMTemplates(); + for ( VMTemplateVO tmplt : rtngTmplts ) { + TemplateDataStoreVO tmpltStore = this._vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); + if ( tmpltStore == null ) { + tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, tmplt.getUrl()); + tmpltStore.setSize(0); + tmpltStore.setPhysicalSize(0); // no size information for pre-seeded system vm templates + _vmTemplateStoreDao.persist(tmpltStore); + } + } + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index 1d24f12b2e0..f43bc4093f3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -68,6 +68,7 @@ public class ImageStoreHelper { store.setProtocol((String)params.get("protocol")); store.setProviderName((String)params.get("providerName")); store.setScope((ScopeType)params.get("scope")); + store.setDataCenterId((Long)params.get("zoneId")); store.setUuid((String)params.get("uuid")); store.setUrl((String)params.get("url")); store.setRole((DataStoreRole)params.get("role")); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index 4ae0d17ac67..97f87b7dbf9 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -35,6 +35,8 @@ import javax.ejb.Local; 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.DataStoreManager; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -97,6 +99,7 @@ import com.google.gson.Gson; import com.vmware.vim25.AboutInfo; import com.vmware.vim25.HostConnectSpec; import com.vmware.vim25.ManagedObjectReference; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;; @Local(value = {VmwareManager.class}) @@ -120,6 +123,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Inject CommandExecLogDao _cmdExecLogDao; @Inject ClusterManager _clusterMgr; @Inject SecondaryStorageVmManager _ssvmMgr; + @Inject DataStoreManager _dataStoreMgr; @Inject CiscoNexusVSMDeviceDao _nexusDao; @Inject ClusterVSMMapDao _vsmMapDao; @Inject ConfigurationDao _configDao; @@ -426,9 +430,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Override public String getSecondaryStorageStoreUrl(long dcId) { - List secStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dcId); - if(secStorageHosts.size() > 0) - return secStorageHosts.get(0).getStorageUrl(); + DataStore secStore = this._dataStoreMgr.getImageStore(dcId); + if(secStore != null) + return secStore.getUri(); return null; } diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 4328e2a756c..234d4102996 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2665,7 +2665,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (onlyReady){ - sc.addAnd("downlaadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); + sc.addAnd("downloadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); } @@ -2675,7 +2675,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (!showDomr){ // excluding system template - sc.addAnd("type", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); + sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); } // search unique templates and find details by Ids diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 2eb93709a7f..798ee56a84d 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1521,18 +1521,22 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); } - List hosts = new ArrayList(); + List hosts = new ArrayList(); if (hostId != null) { - hosts.add(ApiDBUtils.findHostById(hostId)); + hosts.add(hostId); } else { - hosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId); - } + List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); + if (stores != null){ + for (DataStore store : stores){ + hosts.add(store.getId()); + } + } + } CapacityVO capacity = new CapacityVO(hostId, zoneId, null, null, 0, 0, CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE); - for (HostVO host : hosts) { - StorageStats stats = ApiDBUtils.getSecondaryStorageStatistics(host - .getId()); + for (Long id : hosts) { + StorageStats stats = ApiDBUtils.getSecondaryStorageStatistics(id); if (stats == null) { continue; } @@ -1916,6 +1920,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (((ImageStoreProvider) storeProvider).needDownloadSysTemplate()) { // trigger system vm template download this._imageSrv.downloadBootstrapSysTemplate(store); + } else { + // populate template_store_ref table + this._imageSrv.addSystemVMTemplatesToSecondary(store); } return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); diff --git a/server/src/com/cloud/storage/s3/S3ManagerImpl.java b/server/src/com/cloud/storage/s3/S3ManagerImpl.java index cf236b8b9d3..1e8ad4f54ed 100644 --- a/server/src/com/cloud/storage/s3/S3ManagerImpl.java +++ b/server/src/com/cloud/storage/s3/S3ManagerImpl.java @@ -48,6 +48,8 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.command.admin.storage.AddS3Cmd; import org.apache.cloudstack.api.command.admin.storage.ListS3sCmd; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -116,8 +118,9 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { @Inject private HostDao hostDao; + @Inject - private SecondaryStorageVmManager secondaryStorageVMManager; + private DataStoreManager dataStoreManager; public S3ManagerImpl() { } @@ -319,11 +322,10 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { return errorMessage; } - final HostVO secondaryStorageHost = secondaryStorageVMManager - .findSecondaryStorageHost(dataCenterId); - if (secondaryStorageHost == null) { + final DataStore secondaryStore = this.dataStoreManager.getImageStore(dataCenterId); + if (secondaryStore == null) { final String errorMessage = format( - "Unable to find secondary storage host for zone id %1$s.", + "Unable to find secondary storage for zone id %1$s.", dataCenterId); LOGGER.error(errorMessage); throw new CloudRuntimeException(errorMessage); @@ -331,7 +333,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { final long accountId = template.getAccountId(); final DownloadTemplateFromS3ToSecondaryStorageCommand cmd = new DownloadTemplateFromS3ToSecondaryStorageCommand( - s3, accountId, templateId, secondaryStorageHost.getName(), + s3, accountId, templateId, secondaryStore.getName(), primaryStorageDownloadWait); try { @@ -358,7 +360,7 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { asList("template", "tmpl", accountId, templateId), File.separator); final VMTemplateHostVO tmpltHost = new VMTemplateHostVO( - secondaryStorageHost.getId(), templateId, + secondaryStore.getId(), templateId, now(), 100, Status.DOWNLOADED, null, null, null, installPath, template.getUrl()); tmpltHost.setSize(templateS3VO.getSize()); diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index c4fd848f9f4..a75174645b0 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -508,8 +508,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } protected Map createSecStorageVmInstance(long dataCenterId, SecondaryStorageVm.Role role) { - HostVO secHost = findSecondaryStorageHost(dataCenterId); - if (secHost == null) { + DataStore secStore = this._dataStoreMgr.getImageStore(dataCenterId); + if (secStore == null) { String msg = "No secondary storage available in zone " + dataCenterId + ", cannot create secondary storage vm"; s_logger.warn(msg); throw new CloudRuntimeException(msg); @@ -1019,8 +1019,8 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar Map details = _vmDetailsDao.findDetails(vm.getId()); vm.setDetails(details); - HostVO secHost = _ssvmMgr.findSecondaryStorageHost(dest.getDataCenter().getId()); - assert (secHost != null); + DataStore secStore = this._dataStoreMgr.getImageStore(dest.getDataCenter().getId()); + assert (secStore != null); StringBuilder buf = profile.getBootArgsBuilder(); buf.append(" template=domP type=secstorage"); @@ -1265,9 +1265,9 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar List ssVms = _secStorageVmDao.getSecStorageVmListInStates(SecondaryStorageVm.Role.templateProcessor, dataCenterId, State.Running, State.Migrating, State.Starting, State.Stopped, State.Stopping ); int vmSize = (ssVms == null)? 0 : ssVms.size(); - List ssHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(dataCenterId); - int hostSize = (ssHosts == null)? 0 : ssHosts.size(); - if ( hostSize > vmSize ) { + List ssStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dataCenterId)); + int storeSize = (ssStores == null)? 0 : ssStores.size(); + if ( storeSize > vmSize ) { s_logger.info("No secondary storage vms found in datacenter id=" + dataCenterId + ", starting a new one"); return new Pair(AfterScanAction.expand, SecondaryStorageVm.Role.templateProcessor); } @@ -1356,19 +1356,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar return null; } - @Override - public HostVO findSecondaryStorageHost(long dcId) { - SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); - sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.SecondaryStorage); - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); - List storageHosts = sc.list(); - if (storageHosts == null || storageHosts.size() < 1) { - return null; - } else { - Collections.shuffle(storageHosts); - return storageHosts.get(0); - } - } @Override public List listSecondaryStorageHostsInAllZones() { @@ -1377,29 +1364,7 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar return sc.list(); } - @Override - public List listSecondaryStorageHostsInOneZone(long dataCenterId) { - SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dataCenterId); - sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.SecondaryStorage); - return sc.list(); - } - @Override - public List listLocalSecondaryStorageHostsInOneZone(long dataCenterId) { - SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dataCenterId); - sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.LocalSecondaryStorage); - return sc.list(); - } - - @Override - public List listAllTypesSecondaryStorageHostsInOneZone(long dataCenterId) { - SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dataCenterId); - sc.addAnd(sc.getEntity().getType(), Op.IN, Host.Type.LocalSecondaryStorage, Host.Type.SecondaryStorage); - return sc.list(); - } @Override public List listUpAndConnectingSecondaryStorageVmHost(Long dcId) { diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java index 0756c72d59e..e4651df3fa6 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java @@ -18,8 +18,6 @@ package com.cloud.storage.secondary; import java.util.List; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; - import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.host.HostVO; @@ -47,12 +45,7 @@ public interface SecondaryStorageVmManager extends Manager { public Pair assignSecStorageVm(long zoneId, Command cmd); boolean generateSetupCommand(Long hostId); - //boolean deleteHost(Long hostId); - public HostVO findSecondaryStorageHost(long dcId); public List listSecondaryStorageHostsInAllZones(); - public List listSecondaryStorageHostsInOneZone(long dataCenterId); - public List listLocalSecondaryStorageHostsInOneZone(long dataCenterId); - public List listAllTypesSecondaryStorageHostsInOneZone(long dataCenterId); public List listUpAndConnectingSecondaryStorageVmHost(Long dcId); public HostVO pickSsvmHost(HostVO ssHost); } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index cb0bee9cc76..ae1e1788070 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.api.command.user.iso.DeleteIsoCmd; import org.apache.cloudstack.api.command.user.iso.RegisterIsoCmd; import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd; import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.TemplateDataFactory; @@ -47,38 +46,24 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.Resource.ResourceType; -import com.cloud.dc.DataCenterVO; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; -import com.cloud.host.HostVO; -import com.cloud.storage.ScopeType; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.DataStoreRole; import com.cloud.storage.TemplateProfile; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.user.Account; import com.cloud.utils.UriUtils; import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.UserVmVO; @Local(value=TemplateAdapter.class) public class HypervisorTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter { private final static Logger s_logger = Logger.getLogger(HypervisorTemplateAdapter.class); @Inject DownloadMonitor _downloadMonitor; - @Inject SecondaryStorageVmManager _ssvmMgr; @Inject AgentManager _agentMgr; @Inject DataStoreManager storeMgr; @@ -196,10 +181,10 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te .createTemplateAsync(tmpl, imageStore, caller); } _resourceLimitMgr.incrementResourceCount(profile.getAccountId(), ResourceType.template); - + return template; } - + private class CreateTemplateContext extends AsyncRpcConext { final TemplateInfo template; public CreateTemplateContext(AsyncCompletionCallback callback, TemplateInfo template) { @@ -207,15 +192,15 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te this.template = template; } } - - protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher callback, CreateTemplateContext context) { TemplateInfo template = context.template; VMTemplateVO tmplt = this._tmpltDao.findById(template.getId()); long accountId = tmplt.getAccountId(); _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize()); - + return null; } @@ -280,7 +265,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te } - public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { + @Override + public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) { TemplateProfile profile = super.prepareDelete(cmd); VMTemplateVO template = (VMTemplateVO)profile.getTemplate(); Long zoneId = profile.getZoneId(); @@ -289,19 +275,20 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te throw new InvalidParameterValueException("The DomR template cannot be deleted."); } - if (zoneId != null && (_ssvmMgr.findSecondaryStorageHost(zoneId) == null)) { - throw new InvalidParameterValueException("Failed to find a secondary storage host in the specified zone."); + if (zoneId != null && (this.storeMgr.getImageStore(zoneId) == null)) { + throw new InvalidParameterValueException("Failed to find a secondary storage in the specified zone."); } return profile; } - public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { + @Override + public TemplateProfile prepareDelete(DeleteIsoCmd cmd) { TemplateProfile profile = super.prepareDelete(cmd); Long zoneId = profile.getZoneId(); - if (zoneId != null && (_ssvmMgr.findSecondaryStorageHost(zoneId) == null)) { - throw new InvalidParameterValueException("Failed to find a secondary storage host in the specified zone."); + if (zoneId != null && (this.storeMgr.getImageStore(zoneId) == null)) { + throw new InvalidParameterValueException("Failed to find a secondary storage in the specified zone."); } return profile; From 52799f46a485c1a9fa8ed8e76b1cabd777583e40 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 1 May 2013 14:00:53 -0700 Subject: [PATCH 083/303] fix data motion --- .../subsystem/api/storage/SnapshotInfo.java | 1 - .../motion/AncientDataMotionStrategy.java | 22 ++++++-- .../storage/snapshot/SnapshotObject.java | 50 +++++++++++++------ 3 files changed, 53 insertions(+), 20 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java index 2973a545c94..41ea5f3dd3c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java @@ -26,6 +26,5 @@ public interface SnapshotInfo extends DataObject, Snapshot { public VolumeInfo getBaseVolume(); public void addPayload(Object data); Long getDataCenterId(); - public Long getPrevSnapshotId(); ObjectInDataStoreStateMachine.State getStatus(); } 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 index 2075ef60b9c..5b8cbf68e1b 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -29,6 +29,7 @@ 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; @@ -136,6 +137,21 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { // TODO Auto-generated method stub return true; } + + protected boolean needCacheStorage(DataObject srcData, DataObject destData) { + DataTO srcTO = srcData.getTO(); + DataTO destTO = destData.getTO(); + DataStoreTO srcStoreTO = srcTO.getDataStore(); + DataStoreTO destStoreTO = destTO.getDataStore(); + if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) { + return false; + } + + if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) { + return false; + } + return true; + } @DB protected Answer copyVolumeFromImage(DataObject srcData, DataObject destData) { @@ -143,7 +159,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + if (needCacheStorage(srcData, destData)) { //need to copy it to image cache store DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); @@ -162,7 +178,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { private Answer copyTemplate(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); - if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + if (needCacheStorage(srcData, destData)) { //need to copy it to image cache store DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); @@ -330,7 +346,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait .getDefaultValue())); - if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + if (needCacheStorage(srcData, destData)) { //need to copy it to image cache store DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _createprivatetemplatefromvolumewait); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 6fddcdacbbe..c19efb0d47f 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -26,6 +26,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -45,6 +46,9 @@ import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; +import com.cloud.utils.db.SearchCriteria.Op; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; @@ -59,9 +63,11 @@ public class SnapshotObject implements SnapshotInfo { @Inject protected VolumeDataFactory volFactory; @Inject protected SnapshotStateMachineManager stateMachineMgr; @Inject + SnapshotDataFactory snapshotFactory; + @Inject ObjectInDataStoreManager ojbectInStoreMgr; @Inject - SnapshotDataStoreDao snapshotStore; + SnapshotDataStoreDao snapshotStoreDao; public SnapshotObject() { } @@ -83,15 +89,30 @@ public class SnapshotObject implements SnapshotInfo { @Override public SnapshotInfo getParent() { + SnapshotDataStoreVO snapStoreVO = this.snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), this.store.getId(), this.snapshot.getId()); + if (snapStoreVO == null) { + return null; + } - // TODO Auto-generated method stub - return null; + long parentId = snapStoreVO.getParentSnapshotId(); + if (parentId == 0) { + return null; + } + + return this.snapshotFactory.getSnapshot(parentId, store); } @Override public SnapshotInfo getChild() { - // TODO Auto-generated method stub - return null; + SearchCriteriaService sc = SearchCriteria2.create(SnapshotDataStoreVO.class); + sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, this.store.getId()); + sc.addAnd(sc.getEntity().getRole(), Op.EQ, this.store.getRole()); + sc.addAnd(sc.getEntity().getParentSnapshotId(), Op.EQ, this.getId()); + SnapshotDataStoreVO vo = sc.find(); + if (vo == null) { + return null; + } + return this.snapshotFactory.getSnapshot(vo.getId(), store); } @Override @@ -211,37 +232,34 @@ public class SnapshotObject implements SnapshotInfo { stateMachineMgr.processEvent(this.snapshot, event); } - @Override - public Long getPrevSnapshotId() { - SnapshotDataStoreVO snapshotStoreVO = this.snapshotStore.findBySnapshot(this.getId(), this.getDataStore().getRole()); - return snapshotStoreVO.getParentSnapshotId(); - } - public SnapshotVO getSnapshotVO(){ return this.snapshot; } @Override public DataTO getTO() { - // TODO Auto-generated method stub - return null; + DataTO to = this.store.getDriver().getTO(this); + if (to == null) { + return new SnapshotObjectTO(this); + } + return to; } @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { - SnapshotDataStoreVO snapshotStore = this.snapshotStore.findByStoreSnapshot(this.getDataStore().getRole(), + SnapshotDataStoreVO snapshotStore = this.snapshotStoreDao.findByStoreSnapshot(this.getDataStore().getRole(), this.getDataStore().getId(), this.getId()); if (answer instanceof CreateObjectAnswer) { SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CreateObjectAnswer) answer).getData(); snapshotStore.setInstallPath(snapshotTO.getPath()); - this.snapshotStore.update(snapshotStore.getId(), snapshotStore); + this.snapshotStoreDao.update(snapshotStore.getId(), snapshotStore); } else if (answer instanceof CopyCmdAnswer) { SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CopyCmdAnswer) answer).getNewData(); snapshotStore.setInstallPath(snapshotTO.getPath()); if (snapshotTO.getParentSnapshotPath() == null) { snapshotStore.setParentSnapshotId(0L); } - this.snapshotStore.update(snapshotStore.getId(), snapshotStore); + this.snapshotStoreDao.update(snapshotStore.getId(), snapshotStore); } else { throw new CloudRuntimeException("Unknown answer: " + answer.getClass()); } From 8a5bd9e8f84e5206ac1a73611fc396a33bb8abcd Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 1 May 2013 16:04:40 -0700 Subject: [PATCH 084/303] Fix a sql bug in selecting end point to send message. --- .../storage/RemoteHostEndPoint.java | 2 +- .../ObjectInDataStoreManagerImpl.java | 9 ++ .../endpoint/DefaultEndPointSelector.java | 4 +- .../datastore/PrimaryDataStoreImpl.java | 8 +- .../resource/XenServerStorageResource.java | 124 +++++++++--------- setup/db/db/schema-410to420.sql | 1 + 6 files changed, 82 insertions(+), 66 deletions(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index acf78f24a89..4c6dd0f6a5d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -48,7 +48,7 @@ public class RemoteHostEndPoint implements EndPoint { HostEndpointRpcServer rpcServer; private ScheduledExecutorService executor; - protected RemoteHostEndPoint() { + public RemoteHostEndPoint() { executor = Executors.newScheduledThreadPool(10); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index f16afa003fa..4cf813918d1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -219,10 +219,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { switch (data.getType()){ case TEMPLATE: this.stateMachines.transitTo(obj, event, null, templateDataStoreDao); + break; case SNAPSHOT: this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao); + break; case VOLUME: this.stateMachines.transitTo(obj, event, null, volumeDataStoreDao); + break; } } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { @@ -262,10 +265,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { switch (type){ case TEMPLATE: vo = templateDataStoreDao.findByStoreTemplate(dataStoreId, objId); + break; case SNAPSHOT: vo = snapshotDataStoreDao.findByStoreSnapshot(role, dataStoreId, objId); + break; case VOLUME: vo = volumeDataStoreDao.findByStoreVolume(dataStoreId, objId); + break; } } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); @@ -286,10 +292,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { switch (type){ case TEMPLATE: vo = templateDataStoreDao.findByTemplate(objId); + break; case SNAPSHOT: vo = snapshotDataStoreDao.findBySnapshot(objId, role); + break; case VOLUME: vo = volumeDataStoreDao.findByVolume(objId); + break; } if (vo != null) { store = this.storeMgr.getDataStore(vo.getDataStoreId(), DataStoreRole.Image); diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index f48c8e9580c..8415ad2e6d1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -58,9 +58,9 @@ public class DefaultEndPointSelector implements EndPointSelector { @Inject HostDao hostDao; private String findOneHostInaScope = "select id from host where " - + " status == 'Up' and hypervisor_type != 'VMware' and type in ('Routing', 'SecondaryStorageVM') "; + + " status = 'Up' and hypervisor_type != 'VMware' and type in ('Routing', 'SecondaryStorageVM') "; private String findOneHostOnPrimaryStorage = "select id from host where" - + "status == 'Up' and type == 'Routing' "; + + "status = 'Up' and type = 'Routing' "; protected boolean moveBetweenPrimaryImage(DataStore srcStore, DataStore destStore) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 8b20b22af2f..49bfa653114 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -42,6 +42,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; @@ -345,6 +346,11 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public DataStoreTO getTO() { - return getDriver().getStoreTO(this); + DataStoreTO to = getDriver().getStoreTO(this); + if (to == null) { + PrimaryDataStoreTO primaryTO = new PrimaryDataStoreTO(this); + return primaryTO; + } + return to; } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 8d762411fad..d2dfb479f79 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -99,11 +99,11 @@ import com.xensource.xenapi.VDI; public class XenServerStorageResource { private static final Logger s_logger = Logger.getLogger(XenServerStorageResource.class); protected CitrixResourceBase hypervisorResource; - + public XenServerStorageResource(CitrixResourceBase resource) { this.hypervisorResource = resource; } - + public Answer handleStorageCommands(StorageSubSystemCommand command) { if (command instanceof CopyCommand) { return this.execute((CopyCommand)command); @@ -116,9 +116,9 @@ public class XenServerStorageResource { } else if (command instanceof DeleteVolumeCommand) { return execute((DeleteVolumeCommand)command); } - return new Answer((Command)command, false, "not implemented yet"); + return new Answer((Command)command, false, "not implemented yet"); } - + protected SR getSRByNameLabel(Connection conn, String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException { Set srs = SR.getByNameLabel(conn, nameLabel); if (srs.size() != 1) { @@ -127,7 +127,7 @@ public class XenServerStorageResource { SR poolsr = srs.iterator().next(); return poolsr; } - + protected VDI createVdi(Connection conn, String vdiName, SR sr, long size) throws BadServerResponse, XenAPIException, XmlRpcException { VDI.Record vdir = new VDI.Record(); vdir.nameLabel = vdiName; @@ -138,11 +138,11 @@ public class XenServerStorageResource { VDI vdi = VDI.create(conn, vdir); return vdi; } - + protected void deleteVDI(Connection conn, VDI vdi) throws BadServerResponse, XenAPIException, XmlRpcException { vdi.destroy(conn); } - + private Map getParameters(URI uri) { String parameters = uri.getQuery(); Map params = new HashMap(); @@ -153,14 +153,14 @@ public class XenServerStorageResource { } return params; } - + protected CreateObjectAnswer getTemplateSize(CreateObjectCommand cmd, String templateUrl) { /*Connection conn = hypervisorResource.getConnection(); long size = this.getTemplateSize(conn, templateUrl); return new CreateObjectAnswer(cmd, templateUrl, size);*/ return null; } - + protected CreateObjectAnswer createSnapshot(SnapshotObjectTO snapshotTO) { Connection conn = hypervisorResource.getConnection(); long snapshotId = snapshotTO.getId(); @@ -222,7 +222,7 @@ public class XenServerStorageResource { return new CreateObjectAnswer(e.toString()); } } - + protected Answer execute(DeleteVolumeCommand cmd) { VolumeObjectTO volume = null; Connection conn = hypervisorResource.getConnection(); @@ -241,15 +241,15 @@ public class XenServerStorageResource { s_logger.debug("Failed to delete volume", e); errorMsg = e.toString(); } - + return new Answer(cmd, false, errorMsg); } - + /* protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { VolumeObjectTO volume = cmd.getVolume(); ImageOnPrimayDataStoreTO baseImage = cmd.getImage(); Connection conn = hypervisorResource.getConnection(); - + try { VDI baseVdi = VDI.getByUuid(conn, baseImage.getPathOnPrimaryDataStore()); VDI newVol = baseVdi.createClone(conn, new HashMap()); @@ -263,7 +263,7 @@ public class XenServerStorageResource { return new Answer(cmd, false, e.toString()); } }*/ - + protected SR getNfsSR(Connection conn, DecodedDataStore store) { Map deviceConfig = new HashMap(); @@ -272,7 +272,7 @@ public class XenServerStorageResource { try { String server = store.getServer(); String serverpath = store.getPath(); - + serverpath = serverpath.replace("//", "/"); Set srs = SR.getAll(conn); for (SR sr : srs) { @@ -444,7 +444,7 @@ public class XenServerStorageResource { } } }*/ - + protected Answer execute(CreatePrimaryDataStoreCmd cmd) { Connection conn = hypervisorResource.getConnection(); String storeUrl = cmd.getDataStore(); @@ -468,19 +468,19 @@ public class XenServerStorageResource { return new Answer(cmd, false, null); } } - + private long getTemplateSize(Connection conn, String url) { String size = hypervisorResource.callHostPlugin(conn, "storagePlugin", "getTemplateSize", "srcUrl", url); if (size.equalsIgnoreCase("") || size == null) { throw new CloudRuntimeException("Can't get template size"); } - + try { return Long.parseLong(size); } catch (NumberFormatException e) { throw new CloudRuntimeException("Failed to get template lenght", e); } - + /* HttpHead method = new HttpHead(url); DefaultHttpClient client = new DefaultHttpClient(); @@ -500,13 +500,13 @@ public class XenServerStorageResource { throw new CloudRuntimeException("Failed to get template lenght", e); }*/ } - + private void downloadHttpToLocalFile(String destFilePath, String url) { File destFile = new File(destFilePath); if (!destFile.exists()) { throw new CloudRuntimeException("dest file doesn't exist: " + destFilePath); } - + DefaultHttpClient client = new DefaultHttpClient(); HttpGet getMethod = new HttpGet(url); HttpResponse response; @@ -531,15 +531,15 @@ public class XenServerStorageResource { } } } - + //double check the length destFile = new File(destFilePath); if (destFile.length() != length) { throw new CloudRuntimeException("Download file length doesn't match: expected: " + length + ", actual: " + destFile.length()); } - + } - + protected Answer directDownloadHttpTemplate(CopyCommand cmd, DecodedDataObject srcObj, DecodedDataObject destObj) { Connection conn = hypervisorResource.getConnection(); SR poolsr = null; @@ -548,7 +548,7 @@ public class XenServerStorageResource { try { if (destObj.getPath() == null) { //need to create volume at first - + } vdi = VDI.getByUuid(conn, destObj.getPath()); if (vdi == null) { @@ -577,7 +577,7 @@ public class XenServerStorageResource { if (pbdLocation == null) { throw new CloudRuntimeException("Can't get pbd location"); } - + String vdiPath = pbdLocation + "/" + vdiLocation + ".vhd"; //download a url into vdipath //downloadHttpToLocalFile(vdiPath, template.getPath()); @@ -607,7 +607,7 @@ public class XenServerStorageResource { } return new Answer(cmd, false, "Failed to download template"); } - + protected Answer execute(AttachPrimaryDataStoreCmd cmd) { String dataStoreUri = cmd.getDataStore(); Connection conn = hypervisorResource.getConnection(); @@ -640,11 +640,11 @@ public class XenServerStorageResource { return new Answer(cmd, false, msg); } } - + private boolean IsISCSI(String type) { return SRType.LVMOHBA.equals(type) || SRType.LVMOISCSI.equals(type) || SRType.LVM.equals(type) ; } - + private String copy_vhd_from_secondarystorage(Connection conn, String mountpoint, String sruuid, int wait) { String nameLabel = "cloud-" + UUID.randomUUID().toString(); String results = hypervisorResource.callHostPluginAsync(conn, "vmopspremium", "copy_vhd_from_secondarystorage", @@ -668,7 +668,7 @@ public class XenServerStorageResource { s_logger.warn(errMsg); throw new CloudRuntimeException(errMsg); } - + private void destroyVDIbyNameLabel(Connection conn, String nameLabel) { try { Set vdis = VDI.getByNameLabel(conn, nameLabel); @@ -685,7 +685,7 @@ public class XenServerStorageResource { } catch (Exception e){ } } - + protected VDI getVDIbyUuid(Connection conn, String uuid) { try { return VDI.getByUuid(conn, uuid); @@ -695,7 +695,7 @@ public class XenServerStorageResource { throw new CloudRuntimeException(msg, e); } } - + protected String getVhdParent(Connection conn, String primaryStorageSRUuid, String snapshotUuid, Boolean isISCSI) { String parentUuid = hypervisorResource.callHostPlugin(conn, "vmopsSnapshot", "getVhdParent", "primaryStorageSRUuid", primaryStorageSRUuid, "snapshotUuid", snapshotUuid, "isISCSI", isISCSI.toString()); @@ -707,7 +707,7 @@ public class XenServerStorageResource { } return parentUuid; } - + protected CopyCmdAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { DataStoreTO srcStore = srcData.getDataStore(); try { @@ -748,13 +748,13 @@ public class XenServerStorageResource { Thread.sleep(5000); } catch (Exception e) { } - + VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setUuid(snapshotvdi.getUuid(conn)); newVol.setSize(phySize); newVol.setPath(newVol.getUuid()); return new CopyCmdAnswer(newVol); - } + } }catch (Exception e) { String msg = "Catch Exception " + e.getClass().getName() + " for template + " + " due to " + e.toString(); s_logger.warn(msg, e); @@ -762,7 +762,7 @@ public class XenServerStorageResource { } return new CopyCmdAnswer("not implemented yet"); } - + protected CreateObjectAnswer createVolume(DataTO data) throws BadServerResponse, XenAPIException, XmlRpcException { VolumeObjectTO volume = (VolumeObjectTO)data; @@ -786,7 +786,7 @@ public class XenServerStorageResource { return new CreateObjectAnswer(newVol); } - + protected CopyCmdAnswer cloneVolumeFromBaseTemplate(DataTO srcData, DataTO destData) { Connection conn = hypervisorResource.getConnection(); PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); @@ -808,15 +808,15 @@ public class XenServerStorageResource { newVol.setName(vdir.nameLabel); newVol.setSize(vdir.virtualSize); newVol.setPath(vdir.uuid); - + return new CopyCmdAnswer(newVol); } catch (Exception e) { s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: ", e); return new CopyCmdAnswer(e.toString()); } } - - + + protected Answer copyVolumeFromImageCacheToPrimary(DataTO srcData, DataTO destData, int wait) { Connection conn = hypervisorResource.getConnection(); VolumeObjectTO srcVolume = (VolumeObjectTO)srcData; @@ -842,9 +842,9 @@ public class XenServerStorageResource { return new CopyCmdAnswer(e.toString()); } } - + s_logger.debug("unsupported protocol"); - return new CopyCmdAnswer("unsupported protocol"); + return new CopyCmdAnswer("unsupported protocol"); } protected Answer copyVolumeFromPrimaryToSecondary(DataTO srcData, DataTO destData, int wait) { @@ -877,14 +877,14 @@ public class XenServerStorageResource { return new CopyCmdAnswer(newVol); } catch (Exception e) { s_logger.debug("Failed to copy volume to secondary: " + e.toString()); - return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString()); + return new CopyCmdAnswer("Failed to copy volume to secondary: " + e.toString()); } finally { hypervisorResource.removeSR(conn, secondaryStorage); } } - return new CopyCmdAnswer("unsupported protocol"); + return new CopyCmdAnswer("unsupported protocol"); } - + boolean swiftUpload(Connection conn, SwiftTO swift, String container, String ldir, String lfilename, Boolean isISCSI, int wait) { String result = null; try { @@ -900,7 +900,7 @@ public class XenServerStorageResource { } return false; } - + protected String deleteSnapshotBackup(Connection conn, String path, String secondaryStorageMountPath, String backupUUID) { // If anybody modifies the formatting below again, I'll skin them @@ -908,7 +908,7 @@ public class XenServerStorageResource { return result; } - + public void swiftBackupSnapshot(Connection conn, SwiftTO swift, String srUuid, String snapshotUuid, String container, Boolean isISCSI, int wait) { String lfilename; String ldir; @@ -921,7 +921,7 @@ public class XenServerStorageResource { } swiftUpload(conn, swift, container, ldir, lfilename, isISCSI, wait); } - + private static List serializeProperties(final Object object, final Class propertySet) { @@ -968,7 +968,7 @@ public class XenServerStorageResource { return Collections.emptyList(); } - + private boolean backupSnapshotToS3(final Connection connection, final S3TO s3, final String srUuid, final String snapshotUuid, final Boolean iSCSIFlag, final int wait) { @@ -1003,7 +1003,7 @@ public class XenServerStorageResource { return false; } - + protected String backupSnapshot(Connection conn, String primaryStorageSRUuid, String path, String secondaryStorageMountPath, String snapshotUuid, String prevBackupUuid, Boolean isISCSI, int wait) { String backupSnapshotUuid = null; @@ -1019,7 +1019,7 @@ public class XenServerStorageResource { "snapshotUuid", snapshotUuid, "prevBackupUuid", prevBackupUuid, "backupUuid", backupUuid, "isISCSI", isISCSI.toString()); String errMsg = null; if (results == null || results.isEmpty()) { - errMsg = "Could not copy backupUuid: " + backupSnapshotUuid + errMsg = "Could not copy backupUuid: " + backupSnapshotUuid + " from primary storage " + primaryStorageSRUuid + " to secondary storage " + secondaryStorageMountPath + " due to null"; } else { @@ -1046,7 +1046,7 @@ public class XenServerStorageResource { return null; } - + private boolean destroySnapshotOnPrimaryStorageExceptThis(Connection conn, String volumeUuid, String avoidSnapshotUuid){ try { VDI volume = getVDIbyUuid(conn, volumeUuid); @@ -1076,7 +1076,7 @@ public class XenServerStorageResource { return false; } - + protected Answer backupSnasphot(DataTO srcData, DataTO destData, DataTO cacheData, int wait) { Connection conn = hypervisorResource.getConnection(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore(); @@ -1093,11 +1093,11 @@ public class XenServerStorageResource { secondaryStorageUrl = cacheStore.getUrl(); destPath = destData.getPath(); } - + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)srcData; SnapshotObjectTO snapshotOnImage = (SnapshotObjectTO)destData; String snapshotUuid = snapshotTO.getPath(); - + String prevBackupUuid = snapshotOnImage.getParentSnapshotPath(); String prevSnapshotUuid = snapshotTO.getParentSnapshotPath(); @@ -1112,7 +1112,7 @@ public class XenServerStorageResource { } String psUuid = primaryStorageSR.getUuid(conn); Boolean isISCSI = IsISCSI(primaryStorageSR.getType(conn)); - + VDI snapshotVdi = getVDIbyUuid(conn, snapshotUuid); String snapshotPaUuid = null; if ( prevBackupUuid != null ) { @@ -1135,7 +1135,7 @@ public class XenServerStorageResource { String folder = destPath; if (fullbackup) { // the first snapshot is always a full snapshot - + if( !hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, folder)) { details = " Filed to create folder " + folder + " in secondary storage"; s_logger.warn(details); @@ -1147,7 +1147,7 @@ public class XenServerStorageResource { snapshotSr = hypervisorResource.createNfsSRbyURI(conn, new URI(snapshotMountpoint), false); VDI backedVdi = hypervisorResource.cloudVDIcopy(conn, snapshotVdi, snapshotSr, wait); snapshotBackupUuid = backedVdi.getUuid(conn); - + if( destStore instanceof SwiftTO) { try { hypervisorResource.swiftBackupSnapshot(conn, (SwiftTO)destStore, snapshotSr.getUuid(conn), snapshotBackupUuid, "S-" + snapshotTO.getVolume().getVolumeId().toString(), false, wait); @@ -1162,7 +1162,7 @@ public class XenServerStorageResource { } finally { deleteSnapshotBackup(conn, folder, secondaryStorageMountPath, snapshotBackupUuid); } - } + } } finally { if( snapshotSr != null) { @@ -1189,7 +1189,7 @@ public class XenServerStorageResource { } String volumeUuid = snapshotTO.getVolume().getPath(); destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid); - + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); newSnapshot.setPath(snapshotBackupUuid); if (fullbackup) { @@ -1208,14 +1208,14 @@ public class XenServerStorageResource { return new CopyCmdAnswer(details); } - + protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore(); - if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcData.getDataStore().getRole() == DataStoreRole.ImageCache && destData.getDataStore().getRole() == DataStoreRole.Primary) { + if (srcData.getObjectType() == DataObjectType.TEMPLATE && (srcDataStore instanceof NfsTO) && destData.getDataStore().getRole() == DataStoreRole.Primary) { //copy template to primary storage return copyTemplateToPrimaryStorage(srcData, destData, cmd.getWait()); } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 9c492b6c500..318b13b4a5c 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -166,6 +166,7 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `store_role` varchar(255), `size` bigint unsigned, `physical_size` bigint unsigned DEFAULT 0, + `parent_snapshot_id` bigint unsigned DEFAULT 0, `install_path` varchar(255), `state` varchar(255) NOT NULL, `destroyed` tinyint(1) COMMENT 'indicates whether the snapshot_store entry was destroyed by the user or not', From 2812873ffa5b18893100295af64386e8dea398d3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 1 May 2013 17:35:51 -0700 Subject: [PATCH 085/303] Remove methods of searching for secondary storages from host table from SecondaryStorageManagerImpl. --- .../api/storage/DataStoreManager.java | 1 + .../storage/datastore/db/ImageStoreVO.java | 19 +- .../datastore/DataStoreManagerImpl.java | 6 + .../ConfigurationManagerImpl.java | 172 +++++++++--------- .../src/com/cloud/server/StatsCollector.java | 90 +++++---- .../SecondaryStorageManagerImpl.java | 8 - .../secondary/SecondaryStorageVmManager.java | 1 - setup/db/db/schema-410to420.sql | 1 + 8 files changed, 158 insertions(+), 140 deletions(-) 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 4dca1ceab10..e61734aded6 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 @@ -33,4 +33,5 @@ public interface DataStoreManager { public List getImageStoresByProvider(String provider); public List getImageCacheStores(Scope scope); public DataStore registerDataStore(Map params, String providerUuid); + public List listImageStores(); } 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 8e6c6a88a84..fb320477603 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,9 +28,6 @@ import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.TableGenerator; - - - import com.cloud.storage.DataStoreRole; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; @@ -66,20 +63,21 @@ public class ImageStoreVO implements ImageStore { @Enumerated(value = EnumType.STRING) private ScopeType scope; - @Column(name=GenericDao.CREATED_COLUMN) + @Column(name = GenericDao.CREATED_COLUMN) private Date created; - @Column(name=GenericDao.REMOVED_COLUMN) + @Column(name = GenericDao.REMOVED_COLUMN) private Date removed; @Column(name = "role") @Enumerated(value = EnumType.STRING) private DataStoreRole role; - @Column(name="parent") + @Column(name = "parent") private String parent; - + @Column(name="total_size") + private Long totalSize; public DataStoreRole getRole() { return role; @@ -173,6 +171,13 @@ public class ImageStoreVO implements ImageStore { this.parent = parent; } + public Long getTotalSize() { + return totalSize; + } + + public void setTotalSize(Long totalSize) { + this.totalSize = totalSize; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 0ea653b5847..0fdad7ce9f0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -100,4 +100,10 @@ public class DataStoreManagerImpl implements DataStoreManager { public List getImageCacheStores(Scope scope) { return imageDataStoreMgr.listImageCacheStores(scope); } + @Override + public List listImageStores() { + return imageDataStoreMgr.listImageStores(); + } + + } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 1526fb0e125..bf87b18a560 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -5,7 +5,7 @@ // 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, @@ -61,6 +61,8 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd; import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd; import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd; import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -220,7 +222,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Inject AlertManager _alertMgr; // @com.cloud.utils.component.Inject(adapter = SecurityChecker.class) - @Inject + @Inject List _secChecker; @Inject @@ -232,6 +234,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Inject SecondaryStorageVmManager _ssvmMgr; @Inject + DataStoreManager _dataStoreMgr; + @Inject NetworkOfferingServiceMapDao _ntwkOffServiceMapDao; @Inject PhysicalNetworkDao _physicalNetworkDao; @@ -258,11 +262,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override public boolean configure(final String name, final Map params) throws ConfigurationException { String maxVolumeSizeInGbString = _configDao.getValue(Config.MaxVolumeSize.key()); - _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, + _maxVolumeSizeInGb = NumbersUtil.parseInt(maxVolumeSizeInGbString, Integer.parseInt(Config.MaxVolumeSize.getDefaultValue())); String defaultPageSizeString = _configDao.getValue(Config.DefaultPageSize.key()); - _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, + _defaultPageSize = NumbersUtil.parseLong(defaultPageSizeString, Long.parseLong(Config.DefaultPageSize.getDefaultValue())); populateConfigValuesForValidationSet(); @@ -488,8 +492,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return "Please enter either 'true' or 'false'."; } if (Config.SwiftEnable.key().equals(name)) { - List hosts = _ssvmMgr.listSecondaryStorageHostsInAllZones(); - if (hosts != null && hosts.size() > 0) { + List stores = this._dataStoreMgr.listImageStores(); + if (stores != null && stores.size() > 0) { return " can not change " + Config.SwiftEnable.key() + " after you have added secondary storage"; } SwiftVO swift = _swiftDao.findById(1L); @@ -708,7 +712,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati checkPodCidrSubnets(zoneId, podId, cidr); /* * Commenting out due to Bug 11593 - CIDR conflicts with zone when extending pod but not when creating it - * + * * checkCidrVlanOverlap(zoneId, cidr); */ } @@ -1501,7 +1505,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (internalDns2 == null) { internalDns2 = zone.getInternalDns2(); } - + if (guestCidr == null) { guestCidr = zone.getGuestNetworkCidr(); } @@ -1686,7 +1690,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati userNetwork.setBroadcastDomainType(broadcastDomainType); userNetwork.setNetworkDomain(networkDomain); - _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, + _networkMgr.setupNetwork(systemAccount, offering, userNetwork, plan, null, null, false, Domain.ROOT_DOMAIN, null, null, null); } } @@ -2112,9 +2116,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati String endIPv6 = cmd.getEndIpv6(); String ip6Gateway = cmd.getIp6Gateway(); String ip6Cidr = cmd.getIp6Cidr(); - + Account vlanOwner = null; - + boolean ipv4 = (startIP != null); boolean ipv6 = (startIPv6 != null); @@ -2168,7 +2172,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } else if (ipv6) { throw new InvalidParameterValueException("Only support IPv6 on extending existed network"); } - + // Verify that zone exists DataCenterVO zone = _zoneDao.findById(zoneId); if (zone == null) { @@ -2215,18 +2219,18 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } } - - + + // Check if zone is enabled Account caller = UserContext.current().getCaller(); if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())) { throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId); - } + } if (zone.isSecurityGroupEnabled() && zone.getNetworkType() != DataCenter.NetworkType.Basic && forVirtualNetwork) { throw new InvalidParameterValueException("Can't add virtual ip range into a zone with security group enabled"); } - + // If networkId is not specified, and vlan is Virtual or Direct Untagged, try to locate default networks if (forVirtualNetwork) { if (network == null) { @@ -2316,7 +2320,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati //check resource limits _resourceLimitMgr.checkResourceLimit(vlanOwner, ResourceType.public_ip, accountIpRange); - + associateIpRangeToAccount = true; } } @@ -2328,7 +2332,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Transaction txn = Transaction.currentTxn(); txn.start(); - Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, + Vlan vlan = createVlanAndPublicIpRange(zoneId, networkId, physicalNetworkId, forVirtualNetwork, podId, startIP, endIP, vlanGateway, vlanNetmask, vlanId, vlanOwner, startIPv6, endIPv6, ip6Gateway, ip6Cidr); txn.commit(); @@ -2353,39 +2357,39 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Override @DB - public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, + public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) { Network network = _networkModel.getNetwork(networkId); - + boolean ipv4 = false, ipv6 = false; - + if (startIP != null) { ipv4 = true; } - + if (startIPv6 != null) { ipv6 = true; } - + if (!ipv4 && !ipv6) { throw new InvalidParameterValueException("Please specify IPv4 or IPv6 address."); } - + //Validate the zone DataCenterVO zone = _zoneDao.findById(zoneId); if (zone == null) { throw new InvalidParameterValueException("Please specify a valid zone."); } - + // ACL check checkZoneAccess(UserContext.current().getCaller(), zone); - + //Validate the physical network if (_physicalNetworkDao.findById(physicalNetworkId) == null) { throw new InvalidParameterValueException("Please specify a valid physical network id"); } - + //Validate the pod if (podId != null) { Pod pod = _podDao.findById(podId); @@ -2397,11 +2401,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } //pod vlans can be created in basic zone only if (zone.getNetworkType() != NetworkType.Basic || network.getTrafficType() != TrafficType.Guest) { - throw new InvalidParameterValueException("Pod id can be specified only for the networks of type " - + TrafficType.Guest + " in zone of type " + NetworkType.Basic); + throw new InvalidParameterValueException("Pod id can be specified only for the networks of type " + + TrafficType.Guest + " in zone of type " + NetworkType.Basic); } } - + //1) if vlan is specified for the guest network range, it should be the same as network's vlan //2) if vlan is missing, default it to the guest network's vlan if (network.getTrafficType() == TrafficType.Guest) { @@ -2411,7 +2415,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati String[] vlan = uri.toString().split("vlan:\\/\\/"); networkVlanId = vlan[1]; } - + if (vlanId != null) { // if vlan is specified, throw an error if it's not equal to network's vlanId if (networkVlanId != null && !networkVlanId.equalsIgnoreCase(vlanId)) { @@ -2424,14 +2428,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati //vlan id is required for public network throw new InvalidParameterValueException("Vlan id is required when add ip range to the public network"); } - + if (vlanId == null) { vlanId = Vlan.UNTAGGED; } VlanType vlanType = forVirtualNetwork ? VlanType.VirtualNetwork : VlanType.DirectAttached; - - + + if (vlanOwner != null && zone.getNetworkType() != NetworkType.Advanced) { throw new InvalidParameterValueException("Vlan owner can be defined only in the zone of type " + NetworkType.Advanced); } @@ -2447,7 +2451,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("Please specify a valid netmask"); } } - + if (ipv6) { if (!NetUtils.isValidIpv6(vlanIp6Gateway)) { throw new InvalidParameterValueException("Please specify a valid IPv6 gateway"); @@ -2502,7 +2506,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati List vlans = _vlanDao.listByZone(zone.getId()); for (VlanVO vlan : vlans) { String otherVlanGateway = vlan.getVlanGateway(); - // Continue if it's not IPv4 + // Continue if it's not IPv4 if (otherVlanGateway == null) { continue; } @@ -2538,14 +2542,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } } - + String ipv6Range = null; if (ipv6) { ipv6Range = startIPv6; if (endIPv6 != null) { ipv6Range += "-" + endIPv6; } - + List vlans = _vlanDao.listByZone(zone.getId()); for (VlanVO vlan : vlans) { if (vlan.getIp6Gateway() == null) { @@ -2585,14 +2589,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } String ipRange = null; - + if (ipv4) { ipRange = startIP; if (endIP != null) { ipRange += "-" + endIP; } } - + // Everything was fine, so persist the VLAN Transaction txn = Transaction.currentTxn(); txn.start(); @@ -2604,7 +2608,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // IPv6 use a used ip map, is different from ipv4, no need to save public ip range if (ipv4) { if (!savePublicIPRange(startIP, endIP, zoneId, vlan.getId(), networkId, physicalNetworkId)) { - throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support."); + throw new CloudRuntimeException("Failed to save IPv4 range. Please contact Cloud Support."); } } @@ -2630,7 +2634,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (vlan == null) { throw new InvalidParameterValueException("Please specify a valid IP range id."); } - + boolean isAccountSpecific = false; List acctVln = _accountVlanMapDao.listAccountVlanMapsByVlan(vlan.getId()); // Check for account wide pool. It will have an entry for account_vlan_map. @@ -2642,33 +2646,33 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati long allocIpCount = _publicIpAddressDao.countIPs(vlan.getDataCenterId(), vlanDbId, true); boolean success = true; if (allocIpCount > 0) { - if (isAccountSpecific) { + if (isAccountSpecific) { try { vlan = _vlanDao.acquireInLockTable(vlanDbId, 30); if (vlan == null) { throw new CloudRuntimeException("Unable to acquire vlan configuration: " + vlanDbId); } - + if (s_logger.isDebugEnabled()) { s_logger.debug("lock vlan " + vlanDbId + " is acquired"); } - + List ips = _publicIpAddressDao.listByVlanId(vlanDbId); - + for (IPAddressVO ip : ips) { if (ip.isOneToOneNat()) { - throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + + throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip + " belonging to the range is used for static nat purposes. Cleanup the rules first"); } - + if (ip.isSourceNat() && _networkModel.getNetwork(ip.getAssociatedWithNetworkId()) != null) { - throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + - " as ip " + ip + " belonging to the range is a source nat ip for the network id=" + ip.getSourceNetworkId() + + throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + + " as ip " + ip + " belonging to the range is a source nat ip for the network id=" + ip.getSourceNetworkId() + ". IP range with the source nat ip address can be removed either as a part of Network, or account removal"); } - + if (_firewallDao.countRulesByIpId(ip.getId()) > 0) { - throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + + throw new InvalidParameterValueException("Can't delete account specific vlan " + vlanDbId + " as ip " + ip + " belonging to the range has firewall rules applied. Cleanup the rules first"); } //release public ip address here @@ -2679,7 +2683,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } finally { _vlanDao.releaseFromLockTable(vlanDbId); - } + } } else { throw new InvalidParameterValueException("The IP range can't be deleted because it has allocated public IP addresses."); } @@ -2759,7 +2763,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return true; } - + @DB protected boolean savePublicIPRange(String startIP, String endIP, long zoneId, long vlanDbId, long sourceNetworkid, long physicalNetworkId) { @@ -2962,7 +2966,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - + private boolean validPod(long podId) { return (_podDao.findById(podId) != null); } @@ -3180,7 +3184,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (provider == Provider.JuniperSRX) { firewallProvider = Provider.JuniperSRX; } - + if ((service == Service.PortForwarding || service == Service.StaticNat) && provider == Provider.VirtualRouter){ firewallProvider = Provider.VirtualRouter; } @@ -3341,7 +3345,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (!specifyVlan && type == GuestType.Shared) { throw new InvalidParameterValueException("SpecifyVlan should be true if network offering's type is " + type); } - + //specifyIpRanges should always be true for Shared networks //specifyIpRanges can only be true for Isolated networks with no Source Nat service if (specifyIpRanges) { @@ -3365,7 +3369,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (availability == NetworkOffering.Availability.Required) { boolean canOffBeRequired = (type == GuestType.Isolated && serviceProviderMap.containsKey(Service.SourceNat)); if (!canOffBeRequired) { - throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type " + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled"); } @@ -3373,11 +3377,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // only one network offering in the system can be Required List offerings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (!offerings.isEmpty()) { - throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " + Availability.Required); } } - + boolean dedicatedLb = false; boolean elasticLb = false; boolean sharedSourceNat = false; @@ -3386,7 +3390,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati boolean inline = false; if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) { Map lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb); - + if ((lbServiceCapabilityMap != null) && (!lbServiceCapabilityMap.isEmpty())) { String isolationCapability = lbServiceCapabilityMap.get(Capability.SupportedLBIsolation); if (isolationCapability != null) { @@ -3400,7 +3404,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (param != null) { elasticLb = param.contains("true"); } - + String inlineMode = lbServiceCapabilityMap.get(Capability.InlineMode); if (inlineMode != null) { _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.Lb), Service.Lb, Capability.InlineMode, inlineMode); @@ -3414,14 +3418,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if ((sourceNatServiceCapabilityMap != null) && (!sourceNatServiceCapabilityMap.isEmpty())) { String sourceNatType = sourceNatServiceCapabilityMap.get(Capability.SupportedSourceNatTypes); if (sourceNatType != null) { - _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, + _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.SupportedSourceNatTypes, sourceNatType); sharedSourceNat = sourceNatType.contains("perzone"); } String param = sourceNatServiceCapabilityMap.get(Capability.RedundantRouter); if (param != null) { - _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, + _networkModel.checkCapabilityForProvider(serviceProviderMap.get(Service.SourceNat), Service.SourceNat, Capability.RedundantRouter, param); redundantRouter = param.contains("true"); } @@ -3436,7 +3440,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, + NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent); @@ -3463,7 +3467,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati _ntwkOffServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService + " with provider " + provider.getName()); } - + if (vpcOff) { List supportedSvcs = new ArrayList(); supportedSvcs.addAll(serviceProviderMap.keySet()); @@ -3637,7 +3641,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // filter by supported services boolean listBySupportedServices = (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !offerings.isEmpty()); boolean checkIfProvidersAreEnabled = (zoneId != null); - boolean parseOfferings = (listBySupportedServices || sourceNatSupported != null || checkIfProvidersAreEnabled + boolean parseOfferings = (listBySupportedServices || sourceNatSupported != null || checkIfProvidersAreEnabled || forVpc != null || network != null); if (parseOfferings) { @@ -3685,7 +3689,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (sourceNatSupported != null) { addOffering = addOffering && (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.SourceNat) == sourceNatSupported); } - + if (forVpc != null) { addOffering = addOffering && (isOfferingForVpc(offering) == forVpc.booleanValue()); } else if (network != null){ @@ -3803,14 +3807,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } if (availability == null) { - throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + throw new InvalidParameterValueException("Invalid value for Availability. Supported types: " + Availability.Required + ", " + Availability.Optional); } else { if (availability == NetworkOffering.Availability.Required) { - boolean canOffBeRequired = (offeringToUpdate.getGuestType() == GuestType.Isolated + boolean canOffBeRequired = (offeringToUpdate.getGuestType() == GuestType.Isolated && _networkModel.areServicesSupportedByNetworkOffering(offeringToUpdate.getId(), Service.SourceNat)); if (!canOffBeRequired) { - throw new InvalidParameterValueException("Availability can be " + + throw new InvalidParameterValueException("Availability can be " + NetworkOffering.Availability.Required + " only for networkOfferings of type " + GuestType.Isolated + " and with " + Service.SourceNat.getName() + " enabled"); } @@ -3818,7 +3822,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // only one network offering in the system can be Required List offerings = _networkOfferingDao.listByAvailability(Availability.Required, false); if (!offerings.isEmpty() && offerings.get(0).getId() != offeringToUpdate.getId()) { - throw new InvalidParameterValueException("System already has network offering id=" + + throw new InvalidParameterValueException("System already has network offering id=" + offerings.get(0).getId() + " with availability " + Availability.Required); } } @@ -3837,7 +3841,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @ActionEvent(eventType = EventTypes.EVENT_ACCOUNT_MARK_DEFAULT_ZONE, eventDescription = "Marking account with the " + "default zone", async=true) public AccountVO markDefaultZone(String accountName, long domainId, long defaultZoneId) { - + // Check if the account exists Account account = _accountDao.findEnabledAccount(accountName, domainId); if (account == null) { @@ -3851,9 +3855,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } AccountVO acctForUpdate = _accountDao.findById(account.getId()); - + acctForUpdate.setDefaultZoneId(defaultZoneId); - + if (_accountDao.update(account.getId(), acctForUpdate)) { UserContext.current().setEventDetails("Default zone id= " + defaultZoneId); return _accountDao.findById(account.getId()); @@ -3861,7 +3865,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati return null; } } - + // Note: This method will be used for entity name validations in the coming // releases (place holder for now) private void validateEntityName(String str) { @@ -3964,7 +3968,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati Transaction txn = Transaction.currentTxn(); txn.start(); for (AccountVlanMapVO map : maps) { - if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId(), + if (!deleteVlanAndPublicIpRange(_accountMgr.getSystemUser().getId(), map.getVlanDbId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM))) { result = false; } @@ -3989,10 +3993,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati public ClusterVO getCluster(long id) { return _clusterDao.findById(id); } - + @Override public AllocationState findClusterAllocationState(ClusterVO cluster){ - + if(cluster.getAllocationState() == AllocationState.Disabled){ return AllocationState.Disabled; }else if(ApiDBUtils.findPodById(cluster.getPodId()).getAllocationState() == AllocationState.Disabled){ @@ -4000,20 +4004,20 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati }else { DataCenterVO zone = ApiDBUtils.findZoneById(cluster.getDataCenterId()); return zone.getAllocationState(); - } - } + } + } @Override public AllocationState findPodAllocationState(HostPodVO pod){ - + if(pod.getAllocationState() == AllocationState.Disabled){ return AllocationState.Disabled; }else { DataCenterVO zone = ApiDBUtils.findZoneById(pod.getDataCenterId()); return zone.getAllocationState(); - } + } } - + private boolean allowIpRangeOverlap(VlanVO vlan, boolean forVirtualNetwork, long networkId) { // FIXME - delete restriction for virtual network in the future if (vlan.getVlanType() == VlanType.DirectAttached && !forVirtualNetwork) { diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 05be0e2e3af..90491a5de91 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -30,6 +30,12 @@ import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; 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.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; @@ -91,18 +97,21 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc @Inject private UserVmDao _userVmDao; @Inject private VolumeDao _volsDao; @Inject private PrimaryDataStoreDao _storagePoolDao; + @Inject private ImageStoreDao _imageStoreDao; @Inject private StorageManager _storageManager; @Inject private StoragePoolHostDao _storagePoolHostDao; @Inject private SecondaryStorageVmManager _ssvmMgr; + @Inject private DataStoreManager _dataStoreMgr; @Inject private ResourceManager _resourceMgr; @Inject private ConfigurationDao _configDao; + @Inject private EndPointSelector _epSelector; private ConcurrentHashMap _hostStats = new ConcurrentHashMap(); private final ConcurrentHashMap _VmStats = new ConcurrentHashMap(); private ConcurrentHashMap _volumeStats = new ConcurrentHashMap(); private ConcurrentHashMap _storageStats = new ConcurrentHashMap(); private ConcurrentHashMap _storagePoolStats = new ConcurrentHashMap(); - + long hostStatsInterval = -1L; long hostAndVmStatsInterval = -1L; long storageStatsInterval = -1L; @@ -113,12 +122,12 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public static StatsCollector getInstance() { return s_instance; } - + public static StatsCollector getInstance(Map configs) { s_instance.init(configs); return s_instance; } - + public StatsCollector() { s_instance = this; } @@ -140,15 +149,15 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc if (hostStatsInterval > 0) { _executor.scheduleWithFixedDelay(new HostCollector(), 15000L, hostStatsInterval, TimeUnit.MILLISECONDS); } - + if (hostAndVmStatsInterval > 0) { _executor.scheduleWithFixedDelay(new VmStatsCollector(), 15000L, hostAndVmStatsInterval, TimeUnit.MILLISECONDS); } - + if (storageStatsInterval > 0) { _executor.scheduleWithFixedDelay(new StorageCollector(), 15000L, storageStatsInterval, TimeUnit.MILLISECONDS); } - + // -1 means we don't even start this thread to pick up any data. if (volumeStatsInterval > 0) { _executor.scheduleWithFixedDelay(new VolumeCollector(), 15000L, volumeStatsInterval, TimeUnit.MILLISECONDS); @@ -162,7 +171,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public void run() { try { s_logger.debug("HostStatsCollector is running..."); - + SearchCriteria sc = _hostDao.createSearchCriteria(); sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance); @@ -197,13 +206,13 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc } } } - + class VmStatsCollector implements Runnable { @Override public void run() { try { s_logger.debug("VmStatsCollector is running..."); - + SearchCriteria sc = _hostDao.createSearchCriteria(); sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString()); sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance); @@ -214,29 +223,29 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.TrafficMonitor.toString()); sc.addAnd("type", SearchCriteria.Op.NEQ, Host.Type.SecondaryStorageVM.toString()); List hosts = _hostDao.search(sc, null); - + for (HostVO host : hosts) { List vms = _userVmDao.listRunningByHostId(host.getId()); List vmIds = new ArrayList(); - + for (UserVmVO vm : vms) { vmIds.add(vm.getId()); } - + try { HashMap vmStatsById = _userVmMgr.getVirtualMachineStatistics(host.getId(), host.getName(), vmIds); - + if(vmStatsById != null) { VmStatsEntry statsInMemory = null; - + Set vmIdSet = vmStatsById.keySet(); for(Long vmId : vmIdSet) { VmStatsEntry statsForCurrentIteration = vmStatsById.get(vmId); statsInMemory = (VmStatsEntry) _VmStats.get(vmId); - + if(statsInMemory == null) { //no stats exist for this vm, directly persist @@ -249,18 +258,18 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc statsInMemory.setNumCPUs(statsForCurrentIteration.getNumCPUs()); statsInMemory.setNetworkReadKBs(statsInMemory.getNetworkReadKBs() + statsForCurrentIteration.getNetworkReadKBs()); statsInMemory.setNetworkWriteKBs(statsInMemory.getNetworkWriteKBs() + statsForCurrentIteration.getNetworkWriteKBs()); - + _VmStats.put(vmId, statsInMemory); } } } - + } catch (Exception e) { s_logger.debug("Failed to get VM stats for host with ID: " + host.getId()); continue; } } - + } catch (Throwable t) { s_logger.error("Error trying to retrieve VM stats", t); } @@ -278,29 +287,30 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc if (s_logger.isDebugEnabled()) { s_logger.debug("StorageCollector is running..."); } - - List hosts = _ssvmMgr.listSecondaryStorageHostsInAllZones(); + + List stores = _dataStoreMgr.listImageStores(); ConcurrentHashMap storageStats = new ConcurrentHashMap(); - for (HostVO host : hosts) { - if ( host.getStorageUrl() == null ) { + for (DataStore store : stores) { + if ( store.getUri() == null ) { continue; } - GetStorageStatsCommand command = new GetStorageStatsCommand(host.getStorageUrl()); - HostVO ssAhost = _ssvmMgr.pickSsvmHost(host); + GetStorageStatsCommand command = new GetStorageStatsCommand(store.getUri()); + EndPoint ssAhost = _epSelector.select(store); if (ssAhost == null) { - s_logger.debug("There is no secondary storage VM for secondary storage host " + host.getName()); + s_logger.debug("There is no secondary storage VM for secondary storage host " + store.getName()); continue; } - long hostId = host.getId(); - Answer answer = _agentMgr.easySend(ssAhost.getId(), command); + long storeId = store.getId(); + Answer answer = ssAhost.sendMessage(command); if (answer != null && answer.getResult()) { - storageStats.put(hostId, (StorageStats)answer); - s_logger.trace("HostId: "+hostId+ " Used: " + ((StorageStats)answer).getByteUsed() + " Total Available: " + ((StorageStats)answer).getCapacityBytes()); + storageStats.put(storeId, (StorageStats)answer); + s_logger.trace("HostId: "+storeId+ " Used: " + ((StorageStats)answer).getByteUsed() + " Total Available: " + ((StorageStats)answer).getCapacityBytes()); //Seems like we have dynamically updated the sec. storage as prev. size and the current do not match - if (_storageStats.get(hostId)!=null && - _storageStats.get(hostId).getCapacityBytes() != ((StorageStats)answer).getCapacityBytes()){ - host.setTotalSize(((StorageStats)answer).getCapacityBytes()); - _hostDao.update(hostId, host); + if (_storageStats.get(storeId)!=null && + _storageStats.get(storeId).getCapacityBytes() != ((StorageStats)answer).getCapacityBytes()){ + ImageStoreVO imgStore = _imageStoreDao.findById(storeId); + imgStore.setTotalSize(((StorageStats)answer).getCapacityBytes()); + _imageStoreDao.update(storeId, imgStore); } } } @@ -318,7 +328,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc Answer answer = _storageManager.sendToPool(pool.getId(), command); if (answer != null && answer.getResult()) { storagePoolStats.put(pool.getId(), (StorageStats)answer); - + // Seems like we have dynamically updated the pool size since the prev. size and the current do not match if (_storagePoolStats.get(poolId)!= null && _storagePoolStats.get(poolId).getCapacityBytes() != ((StorageStats)answer).getCapacityBytes()){ @@ -342,11 +352,11 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public StorageStats getStorageStats(long id) { return _storageStats.get(id); } - + public HostStats getHostStats(long hostId){ return _hostStats.get(hostId); } - + public StorageStats getStoragePoolStats(long id) { return _storagePoolStats.get(id); } @@ -357,7 +367,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc try { List volumes = _volsDao.listAll(); Map> commandsByPool = new HashMap>(); - + for (VolumeVO volume : volumes) { List commands = commandsByPool.get(volume.getPoolId()); if (commands == null) { @@ -374,7 +384,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc Long poolId = iter.next(); if(poolId != null) { List commandsList = commandsByPool.get(poolId); - + long[] volumeIdArray = new long[commandsList.size()]; Commands commands = new Commands(OnError.Continue); for (int i = 0; i < commandsList.size(); i++) { @@ -382,7 +392,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc volumeIdArray[i] = vCommand.volumeId; commands.addCommand(vCommand.command); } - + List poolhosts = _storagePoolHostDao.listByPoolId(poolId); for(StoragePoolHostVO poolhost : poolhosts) { Answer[] answers = _agentMgr.send(poolhost.getHostId(), commands); @@ -415,7 +425,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public long volumeId; public GetFileStatsCommand command; } - + public VolumeStats[] getVolumeStats(long[] ids) { VolumeStats[] stats = new VolumeStats[ids.length]; if (volumeStatsInterval > 0) { diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index a75174645b0..5d4b43efa46 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -1357,14 +1357,6 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar } - @Override - public List listSecondaryStorageHostsInAllZones() { - SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); - sc.addAnd(sc.getEntity().getType(), Op.EQ, Host.Type.SecondaryStorage); - return sc.list(); - } - - @Override public List listUpAndConnectingSecondaryStorageVmHost(Long dcId) { diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java index e4651df3fa6..4f87346828c 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageVmManager.java @@ -45,7 +45,6 @@ public interface SecondaryStorageVmManager extends Manager { public Pair assignSecStorageVm(long zoneId, Command cmd); boolean generateSetupCommand(Long hostId); - public List listSecondaryStorageHostsInAllZones(); public List listUpAndConnectingSecondaryStorageVmHost(Long dcId); public HostVO pickSsvmHost(HostVO ssHost); } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 318b13b4a5c..ad8bdc44bd4 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -81,6 +81,7 @@ CREATE TABLE `cloud`.`image_store` ( `parent` varchar(255) COMMENT 'parent path for the storage server', `created` datetime COMMENT 'date the image store first signed on', `removed` datetime COMMENT 'date removed if not null', + `total_size` bigint unsigned COMMENT 'storage statistics', PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 50066a602be33a996e44c82efea2928b433020f0 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 1 May 2013 17:37:59 -0700 Subject: [PATCH 086/303] Some code cleanup. --- .../src/com/cloud/configuration/ConfigurationManagerImpl.java | 4 ---- server/src/com/cloud/server/StatsCollector.java | 4 ---- 2 files changed, 8 deletions(-) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index bf87b18a560..873ea1046f7 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -104,7 +104,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.Network; import com.cloud.network.Network.Capability; @@ -147,7 +146,6 @@ import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.S3Dao; import com.cloud.storage.dao.SwiftDao; import com.cloud.storage.s3.S3Manager; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.test.IPRangeConfig; import com.cloud.user.Account; @@ -232,8 +230,6 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati @Inject ProjectManager _projectMgr; @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject DataStoreManager _dataStoreMgr; @Inject NetworkOfferingServiceMapDao _ntwkOffServiceMapDao; diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 90491a5de91..1398672d4d5 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -27,7 +27,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import javax.annotation.PostConstruct; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; @@ -60,7 +59,6 @@ import com.cloud.host.HostStats; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.host.dao.HostDao; -import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePoolHostVO; @@ -69,7 +67,6 @@ import com.cloud.storage.VolumeStats; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.utils.NumbersUtil; import com.cloud.utils.component.ComponentMethodInterceptable; import com.cloud.utils.component.ManagerBase; @@ -100,7 +97,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc @Inject private ImageStoreDao _imageStoreDao; @Inject private StorageManager _storageManager; @Inject private StoragePoolHostDao _storagePoolHostDao; - @Inject private SecondaryStorageVmManager _ssvmMgr; @Inject private DataStoreManager _dataStoreMgr; @Inject private ResourceManager _resourceMgr; @Inject private ConfigurationDao _configDao; From 4d992fd18f710f4ee96e66d09e0e90e5656caf80 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 1 May 2013 17:51:04 -0700 Subject: [PATCH 087/303] fix template download to primary storage --- .../motion/AncientDataMotionStrategy.java | 4 +++- engine/storage/integration-test/pom.xml | 9 ++++++- .../storage/test/ChildTestConfiguration.java | 20 +++++++++++++++- .../test/resource/storageContext.xml | 24 +++++++++---------- .../storage/volume/VolumeServiceImpl.java | 6 ++--- .../resource/XenServerStorageResource.java | 23 ++++++++++-------- tools/devcloud/devcloud.cfg | 2 +- 7 files changed, 57 insertions(+), 31 deletions(-) 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 index 5b8cbf68e1b..66001ad408b 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -307,7 +307,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { errMsg = e.toString(); } CopyCommandResult result = new CopyCommandResult(null, answer); - result.setResult(errMsg); + if (!answer.getResult()) { + result.setResult(answer.getDetails()); + } callback.complete(result); return null; diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 1bce37afd23..4abbf12c961 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -46,7 +46,13 @@ org.apache.cloudstack - cloud-engine-storage-imagemotion + cloud-engine-storage-datamotion + ${project.version} + test + + + org.apache.cloudstack + cloud-engine-storage-cache ${project.version} test @@ -56,6 +62,7 @@ ${project.version} test + org.apache.httpcomponents httpclient diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index 4b8dbb868f2..1895c90ad4b 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.engine.service.api.OrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.rpc.RpcProvider; import org.apache.cloudstack.storage.HostEndpointRpcServer; +import org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl; import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; @@ -69,11 +70,14 @@ import com.cloud.storage.dao.VMTemplatePoolDaoImpl; import com.cloud.storage.dao.VMTemplateZoneDaoImpl; import com.cloud.storage.dao.VolumeDaoImpl; import com.cloud.storage.dao.VolumeHostDaoImpl; +import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.template.TemplateManager; +import com.cloud.user.AccountManager; +import com.cloud.user.ResourceLimitService; import com.cloud.user.dao.UserDaoImpl; import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.VirtualMachineManager; @@ -121,9 +125,9 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; OCFS2ManagerImpl.class, ClusterDetailsDaoImpl.class, SecondaryStorageVmDaoImpl.class, - ConsoleProxyDaoImpl.class, StoragePoolWorkDaoImpl.class, + StorageCacheManagerImpl.class, UserDaoImpl.class }, @@ -147,6 +151,20 @@ public class ChildTestConfiguration extends TestConfiguration { return new MockHostEndpointRpcServerDirectCallResource(); } + @Bean + public ResourceLimitService limtServe() { + return Mockito.mock(ResourceLimitService.class); + } + + @Bean + public DownloadMonitor downloadMonitor() { + return Mockito.mock(DownloadMonitor.class); + } + + @Bean + public AccountManager acctMgt() { + return Mockito.mock(AccountManager.class); + } @Bean public RpcProvider rpcProvider() { return Mockito.mock(RpcProvider.class); diff --git a/engine/storage/integration-test/test/resource/storageContext.xml b/engine/storage/integration-test/test/resource/storageContext.xml index 7c5382d49f9..c4034917983 100644 --- a/engine/storage/integration-test/test/resource/storageContext.xml +++ b/engine/storage/integration-test/test/resource/storageContext.xml @@ -24,20 +24,18 @@ - - - - - - - - - - + - - - + + + + + + + + + + diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index b57333e972a..4e39ddebf09 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -103,7 +103,7 @@ public class VolumeServiceImpl implements VolumeService { @Inject ResourceLimitService _resourceLimitMgr; @Inject - DownloadMonitor _dlMonitor; + DownloadMonitor downloadMonitor; @Inject AccountManager _accountMgr; @Inject @@ -112,8 +112,6 @@ public class VolumeServiceImpl implements VolumeService { @Inject ConfigurationDao configDao; @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject AgentManager _agentMgr; @Inject VolumeDataStoreDao _volumeStoreDao; @@ -815,7 +813,7 @@ public class VolumeServiceImpl implements VolumeService { } s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName()); //TODO: pass a callback later - _dlMonitor.downloadVolumeToStorage(this.volFactory.getVolume(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); + downloadMonitor.downloadVolumeToStorage(this.volFactory.getVolume(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index d2dfb479f79..77e5ca66b5a 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -711,14 +711,13 @@ public class XenServerStorageResource { protected CopyCmdAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { DataStoreTO srcStore = srcData.getDataStore(); try { - if (srcStore.getRole() == DataStoreRole.ImageCache && srcData.getObjectType() == DataObjectType.TEMPLATE) { - ImageStoreTO srcImageStore = (ImageStoreTO)srcStore; + if ((srcStore instanceof NfsTO) && (srcData.getObjectType() == DataObjectType.TEMPLATE)) { + NfsTO srcImageStore = (NfsTO)srcStore; TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData; - String storeUrl = srcImageStore.getUri(); - if (!storeUrl.startsWith("nfs")) { - return new CopyCmdAnswer("only nfs image cache store supported"); - } - String tmplpath = storeUrl + ":" + srcData.getPath(); + String storeUrl = srcImageStore.getUrl(); + + URI uri = new URI(storeUrl); + String tmplpath = uri.getHost() + ":" + uri.getPath() + "/" + srcData.getPath(); PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore(); String poolName = destStore.getUuid(); Connection conn = hypervisorResource.getConnection(); @@ -749,9 +748,8 @@ public class XenServerStorageResource { } catch (Exception e) { } - VolumeObjectTO newVol = new VolumeObjectTO(); + TemplateObjectTO newVol = new TemplateObjectTO(); newVol.setUuid(snapshotvdi.getUuid(conn)); - newVol.setSize(phySize); newVol.setPath(newVol.getUuid()); return new CopyCmdAnswer(newVol); } @@ -1214,8 +1212,13 @@ public class XenServerStorageResource { DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore(); + DataObjectType srcType = srcData.getObjectType(); + DataObjectType destType = destData.getObjectType(); + DataStoreRole destRole = destDataStore.getRole(); + + boolean nfs = (srcDataStore instanceof NfsTO) ? true : false; - if (srcData.getObjectType() == DataObjectType.TEMPLATE && (srcDataStore instanceof NfsTO) && destData.getDataStore().getRole() == DataStoreRole.Primary) { + if ((srcData.getObjectType() == DataObjectType.TEMPLATE) && (srcDataStore instanceof NfsTO) && (destData.getDataStore().getRole() == DataStoreRole.Primary)) { //copy template to primary storage return copyTemplateToPrimaryStorage(srcData, destData, cmd.getWait()); } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg index bf4cc92eed5..0be6026a822 100644 --- a/tools/devcloud/devcloud.cfg +++ b/tools/devcloud/devcloud.cfg @@ -83,7 +83,7 @@ "internaldns1": "192.168.56.1", "secondaryStorages": [ { - "url": "nfs://192.168.56.10:/opt/storage/secondary", + "url": "nfs://192.168.56.10/opt/storage/secondary", "providerName": "CloudStack ImageStore Provider", "details": { } From 164bedd5aeaede4c86719a3b8d4a2916ff41ff20 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 1 May 2013 18:24:47 -0700 Subject: [PATCH 088/303] revive java integration test --- engine/storage/integration-test/pom.xml | 25 ++++++++- .../storage/test/ChildTestConfiguration.java | 15 +++-- .../test/resource/storageContext.xml | 55 ++++++++++++++++++- 3 files changed, 87 insertions(+), 8 deletions(-) diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 4abbf12c961..cd2b229d662 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -62,7 +62,30 @@ ${project.version} test - + + org.apache.cloudstack + cloud-plugin-storage-volume-default + ${project.version} + test + + + org.apache.cloudstack + cloud-plugin-storage-image-default + ${project.version} + test + + + org.apache.cloudstack + cloud-plugin-storage-image-s3 + ${project.version} + test + + + org.apache.cloudstack + cloud-plugin-storage-image-swift + ${project.version} + test + org.apache.httpcomponents httpclient diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index 1895c90ad4b..9a438522c06 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -24,6 +24,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.rpc.RpcProvider; import org.apache.cloudstack.storage.HostEndpointRpcServer; import org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl; +import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; +import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl; +import org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl; import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; @@ -43,12 +46,14 @@ import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; import com.cloud.configuration.dao.ConfigurationDaoImpl; import com.cloud.dc.ClusterDetailsDaoImpl; import com.cloud.dc.dao.ClusterDaoImpl; +import com.cloud.dc.dao.DataCenterDaoImpl; import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; import com.cloud.dc.dao.DataCenterVnetDaoImpl; import com.cloud.dc.dao.DcDetailsDaoImpl; import com.cloud.dc.dao.HostPodDaoImpl; import com.cloud.dc.dao.PodVlanDaoImpl; +import com.cloud.domain.dao.DomainDaoImpl; import com.cloud.host.dao.HostDaoImpl; import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; @@ -61,6 +66,7 @@ import com.cloud.storage.StorageManager; import com.cloud.storage.VolumeManager; import com.cloud.storage.dao.DiskOfferingDaoImpl; import com.cloud.storage.dao.SnapshotDaoImpl; +import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; import com.cloud.storage.dao.StoragePoolHostDaoImpl; import com.cloud.storage.dao.StoragePoolWorkDaoImpl; import com.cloud.storage.dao.VMTemplateDaoImpl; @@ -128,7 +134,10 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; ConsoleProxyDaoImpl.class, StoragePoolWorkDaoImpl.class, StorageCacheManagerImpl.class, - UserDaoImpl.class + UserDaoImpl.class, + DataCenterDaoImpl.class, + StoragePoolDetailsDaoImpl.class, + DomainDaoImpl.class }, includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)}, @@ -136,10 +145,6 @@ useDefaultFilters=false ) public class ChildTestConfiguration extends TestConfiguration { - @Bean - public EndPointSelector selector() { - return Mockito.mock(EndPointSelector.class); - } @Bean public AgentManager agentMgr() { diff --git a/engine/storage/integration-test/test/resource/storageContext.xml b/engine/storage/integration-test/test/resource/storageContext.xml index c4034917983..ba01118b135 100644 --- a/engine/storage/integration-test/test/resource/storageContext.xml +++ b/engine/storage/integration-test/test/resource/storageContext.xml @@ -21,8 +21,6 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> - @@ -37,5 +35,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 238427653652858df402de7d127aa46dc095f095 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 2 May 2013 00:38:11 -0700 Subject: [PATCH 089/303] make template download testable --- .../subsystem/api/storage/TemplateInfo.java | 1 + .../storage/to/TemplateObjectTO.java | 10 +- .../storage/image/store/TemplateObject.java | 13 +- .../storage/test/ChildTestConfiguration.java | 29 +++-- .../storage/test/CloudStackTestNGBase.java | 14 +- .../cloudstack/storage/test/TemplateTest.java | 122 ++++++++++++++++++ .../storage/test/volumeServiceTest.java | 25 +++- .../test/resource/storageContext.xml | 3 +- .../integration-test/test/resource/testng.xml | 1 + .../cloudstack/storage/LocalHostEndpoint.java | 3 +- .../storage/download/DownloadListener.java | 4 +- .../storage/download/DownloadMonitorImpl.java | 23 ---- 12 files changed, 198 insertions(+), 50 deletions(-) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java index 99de1da07fa..2b7eadcc3e5 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java @@ -20,4 +20,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface TemplateInfo extends DataObject { public String getUniqueName(); + public String getInstallPath(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 3a3564aaefa..986a4fc6e91 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -26,6 +26,7 @@ import com.cloud.agent.api.to.DataStoreTO; public class TemplateObjectTO implements DataTO { private String path; + private String origUrl; private String uuid; private DiskFormat diskType; private DataStoreTO imageDataStore; @@ -35,8 +36,9 @@ public class TemplateObjectTO implements DataTO { } public TemplateObjectTO(TemplateInfo template) { - this.path = template.getUri(); + this.path = template.getInstallPath(); this.uuid = template.getUuid(); + this.origUrl = template.getUri(); //this.diskType = template.getDiskType(); this.imageDataStore = template.getDataStore().getTO(); this.name = template.getUniqueName(); @@ -84,4 +86,10 @@ public class TemplateObjectTO implements DataTO { public void setName(String name) { this.name = name; } + public String getOrigUrl() { + return origUrl; + } + public void setOrigUrl(String origUrl) { + this.origUrl = origUrl; + } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 3b19a80bba5..e31b459ce05 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -108,12 +108,9 @@ public class TemplateObject implements TemplateInfo { @Override public String getUri() { VMTemplateVO image = imageDao.findById(this.imageVO.getId()); - if (this.dataStore == null) { + return image.getUrl(); - } else { - DataObjectInStore obj = ojbectInStoreMgr.findObject(this, this.dataStore); - return obj.getInstallPath(); - } + } @Override @@ -218,4 +215,10 @@ public class TemplateObject implements TemplateInfo { return to; } + + @Override + public String getInstallPath() { + DataObjectInStore obj = ojbectInStoreMgr.findObject(this, this.dataStore); + return obj.getInstallPath(); + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index 9a438522c06..f177e83e23b 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -54,6 +54,7 @@ import com.cloud.dc.dao.DcDetailsDaoImpl; import com.cloud.dc.dao.HostPodDaoImpl; import com.cloud.dc.dao.PodVlanDaoImpl; import com.cloud.domain.dao.DomainDaoImpl; +import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDaoImpl; import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; @@ -77,13 +78,16 @@ import com.cloud.storage.dao.VMTemplateZoneDaoImpl; import com.cloud.storage.dao.VolumeDaoImpl; import com.cloud.storage.dao.VolumeHostDaoImpl; import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.download.DownloadMonitorImpl; import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.tags.dao.ResourceTagsDaoImpl; import com.cloud.template.TemplateManager; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; +import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.UserDaoImpl; import com.cloud.utils.component.SpringComponentScanUtils; import com.cloud.vm.VirtualMachineManager; @@ -93,6 +97,7 @@ import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; import com.cloud.vm.dao.UserVmDaoImpl; import com.cloud.vm.dao.UserVmDetailsDaoImpl; +import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDaoImpl; import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; @Configuration @@ -111,7 +116,6 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; HostPodDaoImpl.class, VMTemplateZoneDaoImpl.class, VMTemplateDetailsDaoImpl.class, - HostDaoImpl.class, HostDetailsDaoImpl.class, HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, @@ -137,15 +141,29 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; UserDaoImpl.class, DataCenterDaoImpl.class, StoragePoolDetailsDaoImpl.class, - DomainDaoImpl.class - + DomainDaoImpl.class, + DownloadMonitorImpl.class, + AccountDaoImpl.class }, includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)}, useDefaultFilters=false ) public class ChildTestConfiguration extends TestConfiguration { + @Bean + public SecondaryStorageVmManager secondaryStoreageMgr() { + return Mockito.mock(SecondaryStorageVmManager.class); + } + @Bean + public HostDao hostDao() { + return Mockito.spy(new HostDaoImpl()); + } + + @Bean + public EndPointSelector selector() { + return Mockito.mock(EndPointSelector.class); + } @Bean public AgentManager agentMgr() { return new DirectAgentManagerSimpleImpl(); @@ -161,11 +179,6 @@ public class ChildTestConfiguration extends TestConfiguration { return Mockito.mock(ResourceLimitService.class); } - @Bean - public DownloadMonitor downloadMonitor() { - return Mockito.mock(DownloadMonitor.class); - } - @Bean public AccountManager acctMgt() { return Mockito.mock(AccountManager.class); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index dc7223c9e84..3e9ae482858 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -35,6 +35,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String templateUrl; private String localStorageUuid; private String primaryStorageUrl; + private String secondaryStorage; private Transaction txn; protected void injectMockito() { @@ -61,10 +62,10 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @BeforeMethod(alwaysRun = true) @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add"}) + "primary-storage-want-to-add", "devcloud-secondary-storage"}) protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid, - String primaryStorage) { + String primaryStorage, String secondaryStorage) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -72,6 +73,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.templateUrl = templateUrl; this.localStorageUuid = localStorageUuid; this.primaryStorageUrl = primaryStorage; + this.setSecondaryStorage(secondaryStorage); } protected String getHostGuid() { @@ -101,4 +103,12 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { protected String getPrimaryStorageUrl() { return this.primaryStorageUrl; } + + public String getSecondaryStorage() { + return secondaryStorage; + } + + public void setSecondaryStorage(String secondaryStorage) { + this.secondaryStorage = secondaryStorage; + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java new file mode 100644 index 00000000000..ff540d95748 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -0,0 +1,122 @@ +package org.apache.cloudstack.storage.test; + +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.download.DownloadMonitor; +import com.cloud.storage.download.DownloadMonitorImpl; +import com.cloud.utils.component.ComponentContext; + +@ContextConfiguration(locations={"classpath:/storageContext.xml"}) + +public class TemplateTest extends CloudStackTestNGBase { + @Inject + DataCenterDao dcDao; + ImageStoreVO imageStore; + @Inject + ImageStoreDao imageStoreDao; + @Inject + TemplateService templateSvr; + @Inject + VMTemplateDao templateDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + DataStoreManager dataStoreMgr; + @Inject + EndPointSelector epSelector; + @Inject + DownloadMonitorImpl downloadMonitor; + long dcId; + long templateId; + + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + //create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", + null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + + imageStore = new ImageStoreVO(); + imageStore.setName("test"); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore.setProtocol("nfs"); + imageStore = imageStoreDao.persist(imageStore); + + VMTemplateVO image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + + + //image.setImageDataStoreId(storeId); + image = templateDao.persist(image); + templateId = image.getId(); + + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(new LocalHostEndpoint()); + //Mockito.when(downloadMonitor.isTemplateUpdateable(Mockito.anyLong(), Mockito.anyLong())).thenReturn(true); + } + + @Test + public void registerTemplate() { + TemplateInfo template = templateFactory.getTemplate(templateId); + DataStore store = dataStoreMgr.getImageStore(dcId); + AsyncCallFuture future = new AsyncCallFuture(); + templateSvr.createTemplateAsync(template, store, future); + try { + future.get(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index e47eaec92eb..919ca35aefb 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -21,6 +21,7 @@ package org.apache.cloudstack.storage.test; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -49,6 +50,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeAp import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.RemoteHostEndPoint; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.volume.db.VolumeDao2; @@ -78,6 +81,7 @@ import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; @@ -114,6 +118,9 @@ public class volumeServiceTest extends CloudStackTestNGBase { TemplateDataFactory imageDataFactory; @Inject VolumeDataFactory volumeFactory; + @Inject + ImageStoreDao imageStoreDao; + ImageStoreVO imageStore; Long dcId; Long clusterId; Long podId; @@ -124,12 +131,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); - /* try { - dataStoreProviderMgr.configure(null, new HashMap()); - } catch (ConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - }*/ + host = hostDao.findByGuid(this.getHostGuid()); if (host != null) { dcId = host.getDataCenterId(); @@ -171,6 +173,15 @@ public class volumeServiceTest extends CloudStackTestNGBase { host.setClusterId(cluster.getId()); host = hostDao.persist(host); + + imageStore = new ImageStoreVO(); + imageStore.setName("test"); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore = imageStoreDao.persist(imageStore); //primaryStore = createPrimaryDataStore(); @@ -227,8 +238,10 @@ public class volumeServiceTest extends CloudStackTestNGBase { image.setCrossZones(true); image.setExtractable(true); + //image.setImageDataStoreId(storeId); image = imageDataDao.persist(image); + return image; } diff --git a/engine/storage/integration-test/test/resource/storageContext.xml b/engine/storage/integration-test/test/resource/storageContext.xml index ba01118b135..17f46029726 100644 --- a/engine/storage/integration-test/test/resource/storageContext.xml +++ b/engine/storage/integration-test/test/resource/storageContext.xml @@ -59,7 +59,6 @@ - @@ -88,5 +87,5 @@ - + diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index db32c247d1b..e3d8cd1c86e 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -27,6 +27,7 @@ + diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 8844b4cce9e..7660cf9dadd 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -12,6 +12,7 @@ import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.resource.ServerResource; import com.cloud.storage.download.DownloadListener; import com.cloud.storage.resource.LocalNfsSecondaryStorageResource; @@ -38,7 +39,7 @@ public class LocalHostEndpoint implements EndPoint { @Override public Answer sendMessage(Command cmd) { - if (cmd instanceof CopyCommand) { + if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand)) { return resource.executeRequest(cmd); } // TODO Auto-generated method stub diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index aeb5397e8c1..a3f5bffd496 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -183,8 +183,8 @@ public class DownloadListener implements Listener { if (this.object.getType() == DataObjectType.VOLUME) { dcmd.setResourceType(ResourceType.VOLUME); } - _downloadMonitor.send(_ssAgent.getId(), dcmd, this); - } catch (AgentUnavailableException e) { + _ssAgent.sendMessageAsyncWithListener(dcmd, this); + } catch (Exception e) { s_logger.debug("Send command failed", e); setDisconnected(); } diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index e37a04d0740..d5d01a6a8ff 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -97,14 +97,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject VolumeDataStoreDao _volumeStoreDao; @Inject - AlertManager _alertMgr; - @Inject - protected SwiftManager _swiftMgr; - @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject - StorageManager _storageMgr; - @Inject VMTemplateDao _templateDao = null; @Inject private AgentManager _agentMgr; @@ -113,18 +105,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Inject ConfigurationDao _configDao; @Inject - UserVmManager _vmMgr; - - @Inject - TemplateManager templateMgr; - - @Inject - protected ResourceLimitService _resourceLimitMgr; - @Inject - protected UserVmDao _userVmDao; - @Inject - protected AccountManager _accountMgr; - @Inject EndPointSelector _epSelector; @Inject TemplateDataFactory tmplFactory; @@ -144,9 +124,6 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor final Map _listenerVolumeMap = new ConcurrentHashMap(); final Map _listenerVolMap = new ConcurrentHashMap(); - public void send(Long hostId, Command cmd, Listener listener) throws AgentUnavailableException { - _agentMgr.send(hostId, new Commands(cmd), listener); - } @Override public boolean configure(String name, Map params) { From 87fafb72870ff290e0296d2133e93593ff179784 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 2 May 2013 15:20:46 -0700 Subject: [PATCH 090/303] Add S3 register template integration test. --- .../LocalNfsSecondaryStorageResource.java | 8 +- .../storage/template/TemplateConstants.java | 11 +- .../storage/test/CloudStackTestNGBase.java | 72 +++++++--- .../storage/test/S3TemplateTest.java | 135 ++++++++++++++++++ .../test/resource/s3_testng.xml | 47 ++++++ .../integration-test/test/resource/testng.xml | 3 +- .../cloudstack/storage/LocalHostEndpoint.java | 10 +- .../ObjectInDataStoreManagerImpl.java | 13 +- .../image/datastore/ImageStoreHelper.java | 15 +- .../CloudStackImageStoreDriverImpl.java | 11 +- .../driver/S3ImageStoreDriverImpl.java | 69 +++++++-- .../driver/SwiftImageStoreDriverImpl.java | 56 +++++++- .../storage/download/DownloadListener.java | 4 +- 13 files changed, 392 insertions(+), 62 deletions(-) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java create mode 100644 engine/storage/integration-test/test/resource/s3_testng.xml diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index 282074c850c..3b55e092c2e 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -23,6 +23,7 @@ import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.utils.S3Utils; import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; @@ -31,12 +32,17 @@ import com.cloud.utils.exception.CloudRuntimeException; public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { + public LocalNfsSecondaryStorageResource(){ + _dlMgr = new DownloadManagerImpl(); + } + @Override public Answer executeRequest(Command cmd) { if (cmd instanceof DownloadSystemTemplateCommand){ return execute((DownloadSystemTemplateCommand)cmd); } else { - return Answer.createUnsupportedCommandAnswer(cmd); + //return Answer.createUnsupportedCommandAnswer(cmd); + return super.executeRequest(cmd); } } diff --git a/core/src/com/cloud/storage/template/TemplateConstants.java b/core/src/com/cloud/storage/template/TemplateConstants.java index 5c6de986c17..7b376648b7a 100644 --- a/core/src/com/cloud/storage/template/TemplateConstants.java +++ b/core/src/com/cloud/storage/template/TemplateConstants.java @@ -18,17 +18,18 @@ package com.cloud.storage.template; public final class TemplateConstants { public static final String DEFAULT_TMPLT_ROOT_DIR = "template"; + public static final String DEFAULT_SNAPSHOT_ROOT_DIR = "snapshots"; public static final String DEFAULT_VOLUME_ROOT_DIR = "volumes"; public static final String DEFAULT_TMPLT_FIRST_LEVEL_DIR = "tmpl/"; - + public static final String DEFAULT_SYSTEM_VM_TEMPLATE_PATH = "template/tmpl/1/"; - + public static final String DEFAULT_SYSTEM_VM_TMPLT_NAME = "routing"; - + public static final int DEFAULT_TMPLT_COPY_PORT = 80; public static final String DEFAULT_TMPLT_COPY_INTF = "eth2"; - + public static final String DEFAULT_SSL_CERT_DOMAIN = "realhostip.com"; public static final String DEFAULT_HTTP_AUTH_USER = "cloud"; - + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 3e9ae482858..40267a70c8a 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -37,35 +37,42 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String primaryStorageUrl; private String secondaryStorage; private Transaction txn; - + + private String s3AccessKey; + private String s3SecretKey; + private String s3EndPoint; + private String s3TemplateBucket; + private boolean s3UseHttps; + protected void injectMockito() { - + } - + @BeforeMethod(alwaysRun = true) protected void injectDB(Method testMethod) throws Exception { txn = Transaction.open(testMethod.getName()); } - + @Test protected void injectMockitoTest() { injectMockito(); } - + @AfterMethod(alwaysRun = true) protected void closeDB(Method testMethod) throws Exception { if (txn != null) { txn.close(); } } - + @BeforeMethod(alwaysRun = true) - @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", - "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add", "devcloud-secondary-storage"}) - protected void setup(String hostuuid, String gateway, String cidr, + @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", + "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", + "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps"}) + protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid, - String primaryStorage, String secondaryStorage) { + String primaryStorage, String secondaryStorage, String s3_accessKey, String s3_secretKey, String s3_endpoint, String s3_template_bucket, + String s3_usehttps) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -74,32 +81,38 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.localStorageUuid = localStorageUuid; this.primaryStorageUrl = primaryStorage; this.setSecondaryStorage(secondaryStorage); + // set S3 parameters + this.s3AccessKey = s3_accessKey; + this.s3SecretKey = s3_secretKey; + this.s3EndPoint = s3_endpoint; + this.s3TemplateBucket = s3_template_bucket; + this.s3UseHttps = Boolean.parseBoolean(s3_usehttps); } - + protected String getHostGuid() { return this.hostGuid; } - + protected String getHostGateway() { return this.hostGateway; } - + protected String getHostCidr() { return this.hostCidr; } - + protected String getHostIp() { return this.hostIp; } - + protected String getTemplateUrl() { return this.templateUrl; } - + protected String getLocalStorageUuid() { return this.localStorageUuid; } - + protected String getPrimaryStorageUrl() { return this.primaryStorageUrl; } @@ -111,4 +124,27 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { public void setSecondaryStorage(String secondaryStorage) { this.secondaryStorage = secondaryStorage; } + + public String getS3AccessKey() { + return s3AccessKey; + } + + public String getS3SecretKey() { + return s3SecretKey; + } + + public String getS3EndPoint() { + return s3EndPoint; + } + + public String getS3TemplateBucket() { + return s3TemplateBucket; + } + + public boolean isS3UseHttps() { + return s3UseHttps; + } + + + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java new file mode 100644 index 00000000000..4d4d037de30 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java @@ -0,0 +1,135 @@ +package org.apache.cloudstack.storage.test; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +import javax.inject.Inject; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; +import static org.testng.Assert.assertTrue; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.download.DownloadMonitorImpl; +import com.cloud.utils.component.ComponentContext; + +@ContextConfiguration(locations={"classpath:/storageContext.xml"}) + +public class S3TemplateTest extends CloudStackTestNGBase { + @Inject + DataCenterDao dcDao; + ImageStoreVO imageStore; + ImageStoreDetailVO imageStoreDetail; + @Inject + ImageStoreDao imageStoreDao; + @Inject + TemplateService templateSvr; + @Inject + VMTemplateDao templateDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + DataStoreManager dataStoreMgr; + @Inject + EndPointSelector epSelector; + @Inject + DownloadMonitorImpl downloadMonitor; + @Inject + ImageStoreHelper imageStoreHelper; + long dcId; + long templateId; + + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + //create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", + null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + + + // add s3 image store + Map sParams = new HashMap(); + sParams.put("name", "test"); + sParams.put("protocol", "http"); + sParams.put("providerName", "S3"); + sParams.put("scope", ScopeType.REGION); + sParams.put("role", DataStoreRole.Image); + Map sDetails = new HashMap(); + sDetails.put(ApiConstants.S3_ACCESS_KEY, this.getS3AccessKey()); + sDetails.put(ApiConstants.S3_SECRET_KEY, this.getS3SecretKey()); + sDetails.put(ApiConstants.S3_BUCKET_NAME, this.getS3TemplateBucket()); + sDetails.put(ApiConstants.S3_END_POINT, this.getS3EndPoint()); + this.imageStoreHelper.createImageStore(sParams, sDetails); + + VMTemplateVO image = new VMTemplateVO(); + image.setTemplateType(TemplateType.SYSTEM); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(false); + image.setFeatured(false); + image.setRequiresHvm(false); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(false); + image.setEnableSshKey(false); + image.setGuestOSId(133); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + image = templateDao.persist(image); + templateId = image.getId(); + + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(new LocalHostEndpoint()); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(new LocalHostEndpoint()); + } + + @Test + public void registerTemplate() { + TemplateInfo template = templateFactory.getTemplate(templateId); + DataStore store = dataStoreMgr.getImageStore(dcId); + AsyncCallFuture future = new AsyncCallFuture(); + templateSvr.createTemplateAsync(template, store, future); + try { + TemplateApiResult result = future.get(); + assertTrue(result.isSuccess(), "failed to register template: " + result.getResult()); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } + } + +} diff --git a/engine/storage/integration-test/test/resource/s3_testng.xml b/engine/storage/integration-test/test/resource/s3_testng.xml new file mode 100644 index 00000000000..017cc9ba2f0 --- /dev/null +++ b/engine/storage/integration-test/test/resource/s3_testng.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index e3d8cd1c86e..55f7edf1e0b 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -23,11 +23,12 @@ - + + diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 7660cf9dadd..37e15356b73 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -14,6 +14,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.resource.ServerResource; +import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.download.DownloadListener; import com.cloud.storage.resource.LocalNfsSecondaryStorageResource; import com.cloud.utils.component.ComponentContext; @@ -69,8 +70,13 @@ public class LocalHostEndpoint implements EndPoint { } @Override public void run() { - DownloadAnswer answer = (DownloadAnswer)sendMessage(cmd); - callback.complete(answer); + try { + DownloadAnswer answer = (DownloadAnswer) sendMessage(cmd); + callback.complete(answer); + } catch (Exception ex) { + DownloadAnswer fail = new DownloadAnswer("Error in handling DownloadCommand : " + ex.getMessage(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); + callback.complete(fail); + } } } @Override diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 4cf813918d1..1d891e53ddc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -46,6 +46,7 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.template.TemplateConstants; import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.SearchCriteria2; import com.cloud.utils.db.SearchCriteriaService; @@ -120,9 +121,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { TemplateDataStoreVO ts = new TemplateDataStoreVO(); ts.setTemplateId(obj.getId()); ts.setDataStoreId(dataStore.getId()); - if (dataStore.getRole() == DataStoreRole.ImageCache) { - ts.setInstallPath("template/tmpl/" + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); - } + ts.setInstallPath(TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); ts.setState(ObjectInDataStoreStateMachine.State.Allocated); ts = templateDataStoreDao.persist(ts); break; @@ -131,9 +130,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { ss.setSnapshotId(obj.getId()); ss.setDataStoreId(dataStore.getId()); ss.setRole(dataStore.getRole()); - if (dataStore.getRole() == DataStoreRole.ImageCache) { - ss.setInstallPath("/snapshots/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); - } + ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); ss.setState(ObjectInDataStoreStateMachine.State.Allocated); ss = snapshotDataStoreDao.persist(ss); break; @@ -141,9 +138,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { VolumeDataStoreVO vs = new VolumeDataStoreVO(); vs.setVolumeId(obj.getId()); vs.setDataStoreId(dataStore.getId()); - if (dataStore.getRole() == DataStoreRole.ImageCache) { - vs.setInstallPath("/volumes/" + volumeDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); - } + vs.setInstallPath(TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + volumeDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); vs.setState(ObjectInDataStoreStateMachine.State.Allocated); vs = volumeDataStoreDao.persist(vs); break; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index f43bc4093f3..fe6e94f2853 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.storage.image.datastore; import java.util.Iterator; import java.util.Map; +import java.util.UUID; import javax.inject.Inject; @@ -51,7 +52,12 @@ public class ImageStoreHelper { store.setProtocol((String)params.get("protocol")); store.setProviderName((String)params.get("providerName")); store.setScope((ScopeType)params.get("scope")); - store.setUuid((String)params.get("uuid")); + String uuid = (String)params.get("uuid"); + if (uuid != null) { + store.setUuid(uuid); + } else { + store.setUuid(UUID.randomUUID().toString()); + } store.setUrl((String)params.get("url")); store.setRole(DataStoreRole.getRole((String)params.get("role"))); store = imageStoreDao.persist(store); @@ -69,7 +75,12 @@ public class ImageStoreHelper { store.setProviderName((String)params.get("providerName")); store.setScope((ScopeType)params.get("scope")); store.setDataCenterId((Long)params.get("zoneId")); - store.setUuid((String)params.get("uuid")); + String uuid = (String)params.get("uuid"); + if (uuid != null) { + store.setUuid(uuid); + } else { + store.setUuid(UUID.randomUUID().toString()); + } store.setUrl((String)params.get("url")); store.setRole((DataStoreRole)params.get("role")); store = imageStoreDao.persist(store); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 8e1511c0b9e..c2e4c9c27bd 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -154,18 +154,11 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } } - private class createObjectContext extends AsyncRpcConext { - final DataObject data; - public createObjectContext(AsyncCompletionCallback callback, DataObject data) { - super(callback); - this.data = data; - } - } @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { - createObjectContext context = new createObjectContext(callback, data); + CreateContext context = new CreateContext(callback, data); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); @@ -184,7 +177,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } protected Void createAsyncCallback(AsyncCallbackDispatcher callback, - createObjectContext context) { + CreateContext context) { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; DataStore store = obj.getDataStore(); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 384e7f010e3..31e2fdd6d58 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -35,6 +36,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; @@ -54,6 +56,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; @@ -136,10 +139,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { details.get(ApiConstants.S3_SECRET_KEY), details.get(ApiConstants.S3_END_POINT), details.get(ApiConstants.S3_BUCKET_NAME), - Boolean.parseBoolean(details.get(ApiConstants.S3_HTTPS_FLAG)), - Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TIMEOUT)), - Integer.valueOf(details.get(ApiConstants.S3_MAX_ERROR_RETRY)), - Integer.valueOf(details.get(ApiConstants.S3_SOCKET_TIMEOUT)), + details.get(ApiConstants.S3_HTTPS_FLAG) == null ? false : Boolean.parseBoolean(details.get(ApiConstants.S3_HTTPS_FLAG)), + details.get(ApiConstants.S3_CONNECTION_TIMEOUT) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TIMEOUT)), + details.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_MAX_ERROR_RETRY)), + details.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated()); } @@ -167,22 +170,26 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { + + CreateContext context = new CreateContext(callback, data); + AsyncCallbackDispatcher caller = + AsyncCallbackDispatcher.create(this); + caller.setContext(context); + caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); + + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null); + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); } - - CreateCmdResult result = new CreateCmdResult(null, null); - callback.complete(result); } private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub VolumeVO vol = volumeDao.findById(data.getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Expunging " + vol); @@ -219,6 +226,48 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } } + + protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(store.getId(), updateBuilder); + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSucess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + if (answer.getCheckSum() != null) { + VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); + templateDaoBuilder.setChecksum(answer.getCheckSum()); + templateDao.update(obj.getId(), templateDaoBuilder); + } + + + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; + } + private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { TemplateObject templateObj = (TemplateObject) data; VMTemplateVO template = templateObj.getImage(); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index aa0f3755dd4..4f83d4b30a7 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; @@ -35,6 +36,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; @@ -54,6 +56,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; @@ -161,18 +164,63 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { + CreateContext context = new CreateContext(callback, data); + AsyncCallbackDispatcher caller = + AsyncCallbackDispatcher.create(this); + caller.setContext(context); + caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); + + if (data.getType() == DataObjectType.TEMPLATE) { TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), null); + _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); } else if (data.getType() == DataObjectType.VOLUME) { VolumeObject volInfo = (VolumeObject)data; RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), null); + payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); } + } - CreateCmdResult result = new CreateCmdResult(null, null); - callback.complete(result); + protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(store.getId(), updateBuilder); + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || + answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSucess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + if (answer.getCheckSum() != null) { + VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); + templateDaoBuilder.setChecksum(answer.getCheckSum()); + templateDao.update(obj.getId(), templateDaoBuilder); + } + + + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; } private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index a3f5bffd496..af5d771aef1 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -258,7 +258,9 @@ public class DownloadListener implements Listener { } public void callback(DownloadAnswer answer) { - this._callback.complete(answer); + if ( _callback != null ){ + this._callback.complete(answer); + } } @Override From c60c373a388d97692a9880766451005f052c8d39 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 2 May 2013 23:05:19 -0700 Subject: [PATCH 091/303] Modify DownloadCommand to pass DataTO. --- .../cloud/agent/api/storage/PasswordAuth.java | 39 +++++ .../com/cloud/agent/api/storage/Proxy.java | 72 ++++++++++ .../agent/api/storage/UploadCommand.java | 1 - .../CifsSecondaryStorageResource.java | 4 +- .../LocalNfsSecondaryStorageResource.java | 2 +- .../LocalSecondaryStorageResource.java | 4 +- .../resource/NfsSecondaryStorageResource.java | 6 +- .../storage/template/DownloadManager.java | 7 +- .../storage/template/DownloadManagerImpl.java | 33 +---- .../template/HttpTemplateDownloader.java | 58 ++++---- .../template/S3TemplateDownloader.java | 4 +- .../storage/template/TemplateLocation.java | 2 +- .../cloud/agent/transport/RequestTest.java | 8 +- .../subsystem/api/storage/DataObject.java | 4 +- .../subsystem/api/storage/TemplateInfo.java | 4 +- .../subsystem/api/storage/VolumeInfo.java | 1 + .../storage/command}/DownloadCommand.java | 136 +++++------------- .../command}/DownloadProgressCommand.java | 3 +- .../DownloadSystemTemplateCommand.java | 24 +--- .../storage/to/TemplateObjectTO.java | 82 +++++++++-- .../cloudstack/storage/to/VolumeObjectTO.java | 35 +++-- .../storage/image/TemplateServiceImpl.java | 16 +-- .../storage/image/store/TemplateObject.java | 128 ++++++++++++++++- .../storage/snapshot/SnapshotObject.java | 15 +- .../cloudstack/storage/LocalHostEndpoint.java | 2 +- .../storage/volume/VolumeObject.java | 22 +-- .../storage/volume/VolumeServiceImpl.java | 16 +-- .../agent/manager/MockStorageManager.java | 5 +- .../agent/manager/MockStorageManagerImpl.java | 5 +- .../agent/manager/SimulatorManagerImpl.java | 3 + .../CloudStackImageStoreDriverImpl.java | 13 +- .../driver/S3ImageStoreDriverImpl.java | 14 +- .../driver/SwiftImageStoreDriverImpl.java | 14 +- .../download/DownloadAbandonedState.java | 3 +- .../storage/download/DownloadActiveState.java | 2 +- .../download/DownloadCompleteState.java | 3 +- .../storage/download/DownloadErrorState.java | 2 +- .../storage/download/DownloadListener.java | 8 +- .../storage/download/DownloadMonitor.java | 6 +- .../storage/download/DownloadMonitorImpl.java | 51 +++---- .../storage/download/NotDownloadedState.java | 3 +- .../DummySecondaryStorageResource.java | 4 +- 42 files changed, 522 insertions(+), 342 deletions(-) create mode 100644 api/src/com/cloud/agent/api/storage/PasswordAuth.java create mode 100644 api/src/com/cloud/agent/api/storage/Proxy.java rename {api/src/com/cloud/agent/api/storage => engine/api/src/org/apache/cloudstack/storage/command}/DownloadCommand.java (54%) rename {api/src/com/cloud/agent/api/storage => engine/api/src/org/apache/cloudstack/storage/command}/DownloadProgressCommand.java (96%) rename {api/src/com/cloud/agent/api/storage => engine/api/src/org/apache/cloudstack/storage/command}/DownloadSystemTemplateCommand.java (88%) diff --git a/api/src/com/cloud/agent/api/storage/PasswordAuth.java b/api/src/com/cloud/agent/api/storage/PasswordAuth.java new file mode 100644 index 00000000000..f03c584c660 --- /dev/null +++ b/api/src/com/cloud/agent/api/storage/PasswordAuth.java @@ -0,0 +1,39 @@ +// 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.agent.api.storage; + +/** + * Password authentication + */ +public class PasswordAuth { + + String userName; + String password; + public PasswordAuth() { + + } + public PasswordAuth(String user, String password) { + this.userName = user; + this.password = password; + } + public String getUserName() { + return userName; + } + public String getPassword() { + return password; + } +} diff --git a/api/src/com/cloud/agent/api/storage/Proxy.java b/api/src/com/cloud/agent/api/storage/Proxy.java new file mode 100644 index 00000000000..5adc1146bed --- /dev/null +++ b/api/src/com/cloud/agent/api/storage/Proxy.java @@ -0,0 +1,72 @@ +// 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.agent.api.storage; + +import java.net.URI; + +/** + * Download Proxy + */ +public class Proxy { + private String _host; + private int _port; + private String _userName; + private String _password; + + public Proxy() { + + } + + public Proxy(String host, int port, String userName, String password) { + this._host = host; + this._port = port; + this._userName = userName; + this._password = password; + } + + public Proxy(URI uri) { + this._host = uri.getHost(); + this._port = uri.getPort() == -1 ? 3128 : uri.getPort(); + String userInfo = uri.getUserInfo(); + if (userInfo != null) { + String[] tokens = userInfo.split(":"); + if (tokens.length == 1) { + this._userName = userInfo; + this._password = ""; + } else if (tokens.length == 2) { + this._userName = tokens[0]; + this._password = tokens[1]; + } + } + } + + public String getHost() { + return _host; + } + + public int getPort() { + return _port; + } + + public String getUserName() { + return _userName; + } + + public String getPassword() { + return _password; + } +} diff --git a/api/src/com/cloud/agent/api/storage/UploadCommand.java b/api/src/com/cloud/agent/api/storage/UploadCommand.java index 473bd5b75ac..9b893e2abd5 100644 --- a/api/src/com/cloud/agent/api/storage/UploadCommand.java +++ b/api/src/com/cloud/agent/api/storage/UploadCommand.java @@ -18,7 +18,6 @@ package com.cloud.agent.api.storage; import org.apache.cloudstack.api.InternalIdentity; -import com.cloud.agent.api.storage.DownloadCommand.PasswordAuth; import com.cloud.agent.api.to.TemplateTO; import com.cloud.storage.Upload.Type; import com.cloud.template.VirtualMachineTemplate; diff --git a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java index 435e0f713dc..8ecdc35fcab 100755 --- a/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/CifsSecondaryStorageResource.java @@ -27,6 +27,8 @@ import java.util.Random; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -48,8 +50,6 @@ import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.ssCommand; import com.cloud.host.Host; diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index 3b55e092c2e..06933cc4068 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -11,13 +11,13 @@ import java.net.URISyntaxException; import java.net.URL; import java.util.List; +import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; import org.springframework.stereotype.Component; import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadSystemTemplateCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; diff --git a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java index 5e97c1575dd..7c1a81b43e9 100644 --- a/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalSecondaryStorageResource.java @@ -21,6 +21,8 @@ import java.util.Map; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -35,8 +37,6 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.SecStorageSetupCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupStorageCommand; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ssCommand; diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index efbfaf0db7c..47d5ce7bcba 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -50,6 +50,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -87,15 +90,12 @@ import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.ssCommand; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java index ec424aeb817..1897afd9c00 100644 --- a/core/src/com/cloud/storage/template/DownloadManager.java +++ b/core/src/com/cloud/storage/template/DownloadManager.java @@ -18,10 +18,11 @@ package com.cloud.storage.template; import java.util.Map; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; + import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadCommand.Proxy; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.S3TO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.Storage.ImageFormat; diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index c1391a5f7c1..02a62568856 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -47,6 +47,10 @@ import java.util.concurrent.Executors; import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; @@ -56,11 +60,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadCommand.Proxy; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; -import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.exception.InternalErrorException; @@ -649,29 +649,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } - String installPathPrefix = null; + String installPathPrefix = cmd.getInstallPath(); DataStoreTO dstore = cmd.getDataStore(); - if (dstore instanceof S3TO) { - if (resourceType == ResourceType.TEMPLATE) { - // convention is no / in the end for install path based on - // S3Utils implementation. - // template key is - // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by - // adding template_name in the key, I can avoid generating a - // template.properties file - // for listTemplateCommand. - installPathPrefix = join(asList(_templateDir, cmd.getAccountId(), cmd.getId(), cmd.getName()), S3Utils.SEPARATOR); - } else { - installPathPrefix = join(asList(_volumeDir, cmd.getAccountId(), cmd.getId()), S3Utils.SEPARATOR); - } - } else { - if (ResourceType.TEMPLATE == resourceType) { - installPathPrefix = resource.getRootDir(cmd) + File.separator + _templateDir; - } else { - installPathPrefix = resource.getRootDir(cmd) + File.separator + _volumeDir; - } - } - String user = null; String password = null; if (cmd.getAuth() != null) { diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java index 628ad64c0dc..56da8c0e7d1 100644 --- a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java +++ b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java @@ -29,6 +29,7 @@ import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.Date; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.commons.httpclient.ChunkedInputStream; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; @@ -45,8 +46,7 @@ import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.log4j.Logger; -import com.cloud.agent.api.storage.DownloadCommand.Proxy; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.storage.Proxy; import com.cloud.storage.StorageLayer; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.Pair; @@ -79,7 +79,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { private ResourceType resourceType = ResourceType.TEMPLATE; private final HttpMethodRetryHandler myretryhandler; - + public HttpTemplateDownloader (StorageLayer storageLayer, String downloadUrl, String toDir, DownloadCompleteCallback callback, long maxTemplateSizeInBytes, String user, String password, Proxy proxy, ResourceType resourceType) { this._storage = storageLayer; @@ -88,7 +88,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { this.status = TemplateDownloader.Status.NOT_STARTED; this.resourceType = resourceType; this.MAX_TEMPLATE_SIZE_IN_BYTES = maxTemplateSizeInBytes; - + this.totalBytes = 0; this.client = new HttpClient(s_httpClientManager); @@ -114,7 +114,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { return false; } }; - + try { this.request = new GetMethod(downloadUrl); this.request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler); @@ -122,14 +122,14 @@ public class HttpTemplateDownloader implements TemplateDownloader { //this.request.setFollowRedirects(false); File f = File.createTempFile("dnld", "tmp_", new File(toDir)); - + if (_storage != null) { _storage.setWorldReadableAndWriteable(f); } - + toFile = f.getAbsolutePath(); Pair hostAndPort = validateUrl(downloadUrl); - + if (proxy != null) { client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); if (proxy.getUserName() != null) { @@ -144,7 +144,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { s_logger.info("Added username=" + user + ", password=" + password + "for host " + hostAndPort.first() + ":" + hostAndPort.second()); } else { s_logger.info("No credentials configured for host=" + hostAndPort.first() + ":" + hostAndPort.second()); - } + } } catch (IllegalArgumentException iae) { errorString = iae.getMessage(); status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; @@ -157,7 +157,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { s_logger.warn("throwable caught ", th); } } - + private Pair validateUrl(String url) throws IllegalArgumentException { try { @@ -169,13 +169,13 @@ public class HttpTemplateDownloader implements TemplateDownloader { if (!(port == 80 || port == 443 || port == -1)) { throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); } - + if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { port = 443; } else if (port == -1 && uri.getScheme().equalsIgnoreCase("http")) { port = 80; } - + String host = uri.getHost(); try { InetAddress hostAddr = InetAddress.getByName(host); @@ -197,7 +197,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { throw new IllegalArgumentException(use.getMessage()); } } - + @Override public long download(boolean resume, DownloadCompleteCallback callback) { switch (status) { @@ -211,17 +211,17 @@ public class HttpTemplateDownloader implements TemplateDownloader { int bytes=0; File file = new File(toFile); try { - + long localFileSize = 0; if (file.exists() && resume) { localFileSize = file.length(); s_logger.info("Resuming download to file (current size)=" + localFileSize); } - + Date start = new Date(); int responseCode=0; - + if (localFileSize > 0 ) { // require partial content support for resume request.addRequestHeader("Range", "bytes=" + localFileSize + "-"); @@ -235,7 +235,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { errorString = " HTTP Server returned " + responseCode + " (expected 200 OK) "; return 0; //FIXME: retry? } - + Header contentLengthHeader = request.getResponseHeader("Content-Length"); boolean chunked = false; long remoteSize2 = 0; @@ -255,26 +255,26 @@ public class HttpTemplateDownloader implements TemplateDownloader { if (remoteSize == 0) { remoteSize = remoteSize2; } - + if (remoteSize > MAX_TEMPLATE_SIZE_IN_BYTES) { s_logger.info("Remote size is too large: " + remoteSize + " , max=" + MAX_TEMPLATE_SIZE_IN_BYTES); status = Status.UNRECOVERABLE_ERROR; errorString = "Download file size is too large"; return 0; } - + if (remoteSize == 0) { remoteSize = MAX_TEMPLATE_SIZE_IN_BYTES; } - + InputStream in = !chunked?new BufferedInputStream(request.getResponseBodyAsStream()) : new ChunkedInputStream(request.getResponseBodyAsStream()); - + RandomAccessFile out = new RandomAccessFile(file, "rwd"); out.seek(localFileSize); s_logger.info("Starting download from " + getDownloadUrl() + " to " + toFile + " remoteSize=" + remoteSize + " , max size=" + MAX_TEMPLATE_SIZE_IN_BYTES); - + byte[] block = new byte[CHUNK_SIZE]; long offset=0; boolean done=false; @@ -298,7 +298,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { errorString = "Downloaded " + totalBytes + " bytes " + downloaded; downloadTime += finish.getTime() - start.getTime(); out.close(); - + return totalBytes; }catch (HttpException hte) { status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; @@ -336,8 +336,8 @@ public class HttpTemplateDownloader implements TemplateDownloader { public long getDownloadTime() { return downloadTime; } - - + + public long getDownloadedBytes() { return totalBytes; } @@ -375,7 +375,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { if (remoteSize == 0) { return 0; } - + return (int)(100.0*totalBytes/remoteSize); } @@ -388,7 +388,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { errorString = "Failed to install: " + t.getMessage(); status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; } - + } @Override @@ -424,10 +424,10 @@ public class HttpTemplateDownloader implements TemplateDownloader { return toDir; } - public long getMaxTemplateSizeInBytes() { + public long getMaxTemplateSizeInBytes() { return this.MAX_TEMPLATE_SIZE_IN_BYTES; } - + public static void main(String[] args) { String url ="http:// dev.mysql.com/get/Downloads/MySQL-5.0/mysql-noinstall-5.0.77-win32.zip/from/http://mirror.services.wisc.edu/mysql/"; try { diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index 23f11ab2084..84b2b10f847 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -32,6 +32,7 @@ import java.net.URL; import java.net.UnknownHostException; import java.util.Date; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.commons.httpclient.ChunkedInputStream; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.Header; @@ -52,8 +53,7 @@ import com.amazonaws.services.s3.model.ProgressEvent; import com.amazonaws.services.s3.model.ProgressListener; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.StorageClass; -import com.cloud.agent.api.storage.DownloadCommand.Proxy; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; +import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.S3TO; import com.cloud.utils.Pair; import com.cloud.utils.S3Utils; diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java index 515b1f2343f..eb7a6ec7e62 100644 --- a/core/src/com/cloud/storage/template/TemplateLocation.java +++ b/core/src/com/cloud/storage/template/TemplateLocation.java @@ -24,9 +24,9 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.Properties; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.log4j.Logger; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.storage.template.Processor.FormatInfo; diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 50ea160d232..141beb8650b 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -20,6 +20,8 @@ import java.nio.ByteBuffer; import junit.framework.TestCase; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.junit.Assert; @@ -30,7 +32,6 @@ import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.SecStorageFirewallCfgCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.agent.api.to.NfsTO; import com.cloud.exception.UnsupportedVersionException; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -132,7 +133,10 @@ public class RequestTest extends TestCase { s_logger.info("Testing Download answer"); VMTemplateVO template = new VMTemplateVO(1, "templatename", ImageFormat.QCOW2, true, true, true, TemplateType.USER, "url", true, 32, 1, "chksum", "displayText", true, 30, true, HypervisorType.KVM, null); - DownloadCommand cmd = new DownloadCommand(new NfsTO("secUrl", DataStoreRole.Image), template, 30000000l); + NfsTO nfs = new NfsTO("secUrl", DataStoreRole.Image); + TemplateObjectTO to = new TemplateObjectTO(template); + to.setImageDataStore(nfs); + DownloadCommand cmd = new DownloadCommand(to, 30000000l); Request req = new Request(1, 1, cmd, true); req.logD("Debug for Download"); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index 9bb14c78fa3..8ffed6a1fcd 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -18,8 +18,6 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; - import com.cloud.agent.api.Answer; public interface DataObject { @@ -29,7 +27,7 @@ public interface DataObject { public DataStore getDataStore(); public Long getSize(); public DataObjectType getType(); - public DiskFormat getFormat(); + //public DiskFormat getFormat(); public String getUuid(); public void processEvent(ObjectInDataStoreStateMachine.Event event); public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java index 2b7eadcc3e5..3ee1d2faf01 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java @@ -18,7 +18,9 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -public interface TemplateInfo extends DataObject { +import com.cloud.template.VirtualMachineTemplate; + +public interface TemplateInfo extends DataObject, VirtualMachineTemplate { public String getUniqueName(); public String getInstallPath(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 7165f370bac..b02eaf1866c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -28,4 +28,5 @@ public interface VolumeInfo extends DataObject, Volume { public HypervisorType getHypervisorType(); public Long getLastPoolId(); public String getAttachedVmName(); + public String getInstallPath(); } diff --git a/api/src/com/cloud/agent/api/storage/DownloadCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java similarity index 54% rename from api/src/com/cloud/agent/api/storage/DownloadCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java index 8abc29a8b6b..d70c78623f1 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java @@ -14,91 +14,27 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.agent.api.storage; - -import java.net.URI; +package org.apache.cloudstack.storage.command; import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import com.cloud.agent.api.storage.AbstractDownloadCommand; +import com.cloud.agent.api.storage.PasswordAuth; +import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; -import com.cloud.template.VirtualMachineTemplate; public class DownloadCommand extends AbstractDownloadCommand implements InternalIdentity { - public static class PasswordAuth { - String userName; - String password; - public PasswordAuth() { - - } - public PasswordAuth(String user, String password) { - this.userName = user; - this.password = password; - } - public String getUserName() { - return userName; - } - public String getPassword() { - return password; - } - } public static enum ResourceType { VOLUME, TEMPLATE } - public static class Proxy { - private String _host; - private int _port; - private String _userName; - private String _password; - - public Proxy() { - - } - - public Proxy(String host, int port, String userName, String password) { - this._host = host; - this._port = port; - this._userName = userName; - this._password = password; - } - - public Proxy(URI uri) { - this._host = uri.getHost(); - this._port = uri.getPort() == -1 ? 3128 : uri.getPort(); - String userInfo = uri.getUserInfo(); - if (userInfo != null) { - String[] tokens = userInfo.split(":"); - if (tokens.length == 1) { - this._userName = userInfo; - this._password = ""; - } else if (tokens.length == 2) { - this._userName = tokens[0]; - this._password = tokens[1]; - } - } - } - - public String getHost() { - return _host; - } - - public int getPort() { - return _port; - } - - public String getUserName() { - return _userName; - } - - public String getPassword() { - return _password; - } - } private boolean hvm; private String description; private String checksum; @@ -107,6 +43,7 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal private Long maxDownloadSizeInBytes = null; private long id; private ResourceType resourceType = ResourceType.TEMPLATE; + private String installPath; private DataStoreTO _store; protected DownloadCommand() { @@ -123,46 +60,39 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal this.setSecUrl(that.getSecUrl()); this.maxDownloadSizeInBytes = that.getMaxDownloadSizeInBytes(); this.resourceType = that.resourceType; + this.installPath = that.installPath; + this._store = that._store; } - public DownloadCommand(DataStoreTO store, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { - super(template.getUniqueName(), template.getUrl(), template.getFormat(), template.getAccountId()); - this._store = store; + public DownloadCommand(TemplateObjectTO template, Long maxDownloadSizeInBytes) { + super(template.getName(), template.getOrigUrl(), template.getFormat(), template.getAccountId()); + this._store = template.getDataStore(); + this.installPath = template.getPath(); this.hvm = template.isRequiresHvm(); this.checksum = template.getChecksum(); this.id = template.getId(); - this.description = template.getDisplayText(); - if (store instanceof NfsTO) { - this.setSecUrl(((NfsTO) store).getUrl()); + this.description = template.getDescription(); + if (_store instanceof NfsTO) { + this.setSecUrl(((NfsTO) _store).getUrl()); } this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; } - public DownloadCommand(DataStoreTO store, Volume volume, Long maxDownloadSizeInBytes, String checkSum, String url, ImageFormat format) { - super(volume.getName(), url, format, volume.getAccountId()); - //this.hvm = volume.isRequiresHvm(); - this.checksum = checkSum; - this.id = volume.getId(); - this._store = store; - this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; - this.resourceType = ResourceType.VOLUME; - } - - public DownloadCommand(DataStoreTO store, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { - super(template.getUniqueName(), url, template.getFormat(), template.getAccountId()); - this._store = store; - this.hvm = template.isRequiresHvm(); - this.checksum = template.getChecksum(); - this.id = template.getId(); - this.description = template.getDisplayText(); - if (store instanceof NfsTO) { - this.setSecUrl(((NfsTO) store).getUrl()); - } - this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + public DownloadCommand(TemplateObjectTO template, String user, String passwd, Long maxDownloadSizeInBytes) { + this(template, maxDownloadSizeInBytes); auth = new PasswordAuth(user, passwd); } - public long getId() { + public DownloadCommand(VolumeObjectTO volume, Long maxDownloadSizeInBytes, String checkSum, String url, ImageFormat format) { + super(volume.getName(), url, format, volume.getAccountId()); + this.checksum = checkSum; + this.id = volume.getVolumeId(); + this._store = volume.getDataStore(); + this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + this.resourceType = ResourceType.VOLUME; + } + @Override + public long getId() { return id; } @@ -237,6 +167,16 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal } + public String getInstallPath() { + return installPath; + } + + + public void setInstallPath(String installPath) { + this.installPath = installPath; + } + + } diff --git a/api/src/com/cloud/agent/api/storage/DownloadProgressCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java similarity index 96% rename from api/src/com/cloud/agent/api/storage/DownloadProgressCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java index 835847bedeb..72ca90172b1 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadProgressCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadProgressCommand.java @@ -14,7 +14,8 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.agent.api.storage; +package org.apache.cloudstack.storage.command; + diff --git a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java similarity index 88% rename from api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java rename to engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java index 13678e7085f..864f5b6a931 100644 --- a/api/src/com/cloud/agent/api/storage/DownloadSystemTemplateCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java @@ -14,32 +14,18 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.agent.api.storage; +package org.apache.cloudstack.storage.command; + + import com.cloud.agent.api.Command; -import com.cloud.agent.api.storage.DownloadCommand.Proxy; +import com.cloud.agent.api.storage.PasswordAuth; +import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.template.VirtualMachineTemplate; public class DownloadSystemTemplateCommand extends Command { - public static class PasswordAuth { - String userName; - String password; - public PasswordAuth() { - - } - public PasswordAuth(String user, String password) { - this.userName = user; - this.password = password; - } - public String getUserName() { - return userName; - } - public String getPassword() { - return password; - } - } private PasswordAuth auth; diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 986a4fc6e91..aad5d71536a 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -23,40 +23,86 @@ import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.template.VirtualMachineTemplate; public class TemplateObjectTO implements DataTO { private String path; private String origUrl; private String uuid; - private DiskFormat diskType; + private long id; + private ImageFormat format; + private long accountId; + private String checksum; + private boolean hvm; + private String displayText; private DataStoreTO imageDataStore; private String name; public TemplateObjectTO() { - + } + + public TemplateObjectTO(VirtualMachineTemplate template){ + this.uuid = template.getUuid(); + this.id = template.getId(); + this.origUrl = template.getUrl(); + this.displayText = template.getDisplayText(); + this.checksum = template.getChecksum(); + this.hvm = template.isRequiresHvm(); + this.accountId = template.getAccountId(); + this.name = template.getUniqueName(); + this.format = template.getFormat(); + } + public TemplateObjectTO(TemplateInfo template) { this.path = template.getInstallPath(); this.uuid = template.getUuid(); - this.origUrl = template.getUri(); - //this.diskType = template.getDiskType(); - this.imageDataStore = template.getDataStore().getTO(); + this.id = template.getId(); + this.origUrl = template.getUrl(); + this.displayText = template.getDisplayText(); + this.checksum = template.getChecksum(); + this.hvm = template.isRequiresHvm(); + this.accountId = template.getAccountId(); this.name = template.getUniqueName(); + this.format = template.getFormat(); + this.imageDataStore = template.getDataStore().getTO(); } - + @Override public String getPath() { return this.path; } - + public String getUuid() { return this.uuid; } - - public DiskFormat getDiskType() { - return this.diskType; + + public long getId() { + return id; + } + public ImageFormat getFormat() { + return format; + } + public long getAccountId() { + return accountId; + } + public String getChecksum() { + return checksum; + } + public boolean isRequiresHvm() { + return hvm; + } + public void setRequiresHvm(boolean hvm){ + this.hvm = hvm; + } + public String getDescription() { + return displayText; + } + + public void setDescription(String desc){ + this.displayText = desc; } - public DataStoreTO getImageDataStore() { return this.imageDataStore; } @@ -92,4 +138,18 @@ public class TemplateObjectTO implements DataTO { public void setOrigUrl(String origUrl) { this.origUrl = origUrl; } + public void setFormat(ImageFormat format) { + this.format = format; + } + public void setAccountId(long accountId) { + this.accountId = accountId; + } + public void setChecksum(String checksum) { + this.checksum = checksum; + } + public void setImageDataStore(DataStoreTO imageDataStore) { + this.imageDataStore = imageDataStore; + } + + } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 4ca1f9b3e59..0b8846941ba 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -33,16 +33,16 @@ public class VolumeObjectTO implements DataTO { private long size; private String path; private Long volumeId; - + private long accountId; + public VolumeObjectTO() { } - + public VolumeObjectTO(VolumeInfo volume) { this.uuid = volume.getUuid(); this.path = volume.getUri(); - //this.volumeType = volume.getType(); - //this.diskType = volume.getDiskType(); + this.accountId = volume.getAccountId(); if (volume.getDataStore() != null) { this.dataStore = volume.getDataStore().getTO(); } else { @@ -52,39 +52,39 @@ public class VolumeObjectTO implements DataTO { this.size = volume.getSize(); this.setVolumeId(volume.getId()); } - + public String getUuid() { return this.uuid; } - + public String getPath() { return this.path; } - + public VolumeType getVolumeType() { return this.volumeType; } - + public DiskFormat getDiskType() { return this.diskType; } - + public DataStoreTO getDataStore() { return this.dataStore; } - + public void setDataStore(PrimaryDataStoreTO dataStore) { this.dataStore = dataStore; } - + public String getName() { return this.name; } - + public long getSize() { return this.size; } - + public DataObjectType getObjectType() { return DataObjectType.VOLUME; } @@ -113,4 +113,13 @@ public class VolumeObjectTO implements DataTO { this.volumeId = volumeId; } + public long getAccountId() { + return accountId; + } + + public void setAccountId(long accountId) { + this.accountId = accountId; + } + + } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 79555d48eac..60b3f5389d8 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -187,13 +187,13 @@ public class TemplateServiceImpl implements TemplateService { @Override public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { Set toBeDownloaded = new HashSet(); - List ssHosts = this._storeMgr.getImageStoresByScope(new ZoneScope(dcId)); - if (ssHosts == null || ssHosts.isEmpty()){ + List stores = this._storeMgr.getImageStoresByScope(new ZoneScope(dcId)); + if (stores == null || stores.isEmpty()){ return; } /*Download all the templates in zone with the same hypervisortype*/ - for ( DataStore ssHost : ssHosts) { + for ( DataStore store : stores) { List rtngTmplts = _templateDao.listAllSystemVMTemplates(); List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); @@ -211,10 +211,10 @@ public class TemplateServiceImpl implements TemplateService { } for (VMTemplateVO template: toBeDownloaded) { - TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(ssHost.getId(), template.getId()); + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { - DataObject tmpl = this._templateFactory.getTemplate(template.getId(), ssHost); - _dlMonitor.downloadTemplateToStorage(tmpl, ssHost, null); + TemplateInfo tmplt = this._templateFactory.getTemplate(template.getId()); + this.createTemplateAsync(tmplt, store, null); } } } @@ -370,8 +370,8 @@ public class TemplateServiceImpl implements TemplateService { } s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName()); //TODO: we should pass a callback here - DataObject tmpl = this._templateFactory.getTemplate(tmplt.getId(), store); - _dlMonitor.downloadTemplateToStorage(tmpl, store, null); + TemplateInfo tmpl = this._templateFactory.getTemplate(tmplt.getId()); + this.createTemplateAsync(tmpl, store, null); } } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index e31b459ce05..7ff0cc324b2 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -18,6 +18,9 @@ */ package org.apache.cloudstack.storage.image.store; +import java.util.Date; +import java.util.Map; + import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; @@ -28,7 +31,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -38,7 +40,10 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -108,9 +113,9 @@ public class TemplateObject implements TemplateInfo { @Override public String getUri() { VMTemplateVO image = imageDao.findById(this.imageVO.getId()); - + return image.getUrl(); - + } @Override @@ -153,8 +158,8 @@ public class TemplateObject implements TemplateInfo { } @Override - public DiskFormat getFormat() { - return DiskFormat.valueOf(this.imageVO.getFormat().toString()); + public ImageFormat getFormat() { + return this.imageVO.getFormat(); } public boolean stateTransit(TemplateEvent e) throws NoTransitionException { @@ -188,7 +193,7 @@ public class TemplateObject implements TemplateInfo { templatePoolRef.setInstallPath(newTemplate.getPath()); templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); } - } else if (this.getDataStore().getRole() == DataStoreRole.Image || + } else if (this.getDataStore().getRole() == DataStoreRole.Image || this.getDataStore().getRole() == DataStoreRole.ImageCache) { if (answer instanceof CopyCmdAnswer) { CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; @@ -221,4 +226,115 @@ public class TemplateObject implements TemplateInfo { DataObjectInStore obj = ojbectInStoreMgr.findObject(this, this.dataStore); return obj.getInstallPath(); } + + @Override + public long getAccountId() { + return this.imageVO.getAccountId(); + } + + @Override + public boolean isFeatured() { + return this.imageVO.isFeatured(); + } + + @Override + public boolean isPublicTemplate() { + return this.imageVO.isPublicTemplate(); + } + + @Override + public boolean isExtractable() { + return this.imageVO.isExtractable(); + } + + @Override + public String getName() { + return this.imageVO.getName(); + } + + @Override + public boolean isRequiresHvm() { + return this.imageVO.isRequiresHvm(); + } + + @Override + public String getDisplayText() { + return this.imageVO.getDisplayText(); + } + + @Override + public boolean getEnablePassword() { + return this.imageVO.getEnablePassword(); + } + + @Override + public boolean getEnableSshKey() { + return this.imageVO.getEnableSshKey(); + } + + @Override + public boolean isCrossZones() { + return this.imageVO.isCrossZones(); + } + + @Override + public Date getCreated() { + return this.imageVO.getCreated(); + } + + @Override + public long getGuestOSId() { + return this.imageVO.getGuestOSId(); + } + + @Override + public boolean isBootable() { + return this.imageVO.isBootable(); + } + + @Override + public TemplateType getTemplateType() { + return this.imageVO.getTemplateType(); + } + + @Override + public HypervisorType getHypervisorType() { + return this.imageVO.getHypervisorType(); + } + + @Override + public int getBits() { + return this.imageVO.getBits(); + } + + @Override + public String getUrl() { + return this.imageVO.getUrl(); + } + + @Override + public String getChecksum() { + return this.imageVO.getChecksum(); + } + + @Override + public Long getSourceTemplateId() { + return this.imageVO.getSourceTemplateId(); + } + + @Override + public String getTemplateTag() { + return this.imageVO.getTemplateTag(); + } + + @Override + public Map getDetails() { + return this.imageVO.getDetails(); + } + + @Override + public long getDomainId() { + return this.imageVO.getDomainId(); + } + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index c19efb0d47f..f5800c19bcd 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -30,7 +30,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; @@ -93,12 +92,12 @@ public class SnapshotObject implements SnapshotInfo { if (snapStoreVO == null) { return null; } - + long parentId = snapStoreVO.getParentSnapshotId(); if (parentId == 0) { return null; } - + return this.snapshotFactory.getSnapshot(parentId, store); } @@ -145,10 +144,6 @@ public class SnapshotObject implements SnapshotInfo { return DataObjectType.SNAPSHOT; } - @Override - public DiskFormat getFormat() { - return null; - } @Override public String getUuid() { @@ -247,7 +242,7 @@ public class SnapshotObject implements SnapshotInfo { @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { - SnapshotDataStoreVO snapshotStore = this.snapshotStoreDao.findByStoreSnapshot(this.getDataStore().getRole(), + SnapshotDataStoreVO snapshotStore = this.snapshotStoreDao.findByStoreSnapshot(this.getDataStore().getRole(), this.getDataStore().getId(), this.getId()); if (answer instanceof CreateObjectAnswer) { SnapshotObjectTO snapshotTO = (SnapshotObjectTO)((CreateObjectAnswer) answer).getData(); @@ -274,7 +269,7 @@ public class SnapshotObject implements SnapshotInfo { @Override public void addPayload(Object data) { // TODO Auto-generated method stub - + } - + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 37e15356b73..ea93560934b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -7,12 +7,12 @@ import java.util.concurrent.TimeUnit; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.DownloadCommand; import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; import com.cloud.resource.ServerResource; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.download.DownloadListener; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 567905de522..31a2e6ffa57 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -26,7 +26,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; @@ -78,7 +77,8 @@ public class VolumeObject implements VolumeInfo { vo.configure(dataStore, volumeVO); return vo; } - + + @Override public String getAttachedVmName() { Long vmId = this.volumeVO.getInstanceId(); if (vmId != null) { @@ -97,14 +97,15 @@ public class VolumeObject implements VolumeInfo { return volumeVO.getUuid(); } - public void setPath(String uuid) { - volumeVO.setPath(uuid); + public void setUuid(String uuid) { + volumeVO.setUuid(uuid); } public void setSize(Long size) { volumeVO.setSize(size); } + @Override public Volume.State getState() { return volumeVO.getState(); } @@ -119,6 +120,12 @@ public class VolumeObject implements VolumeInfo { return volumeVO.getSize(); } + @Override + public String getInstallPath() { + DataObjectInStore obj = ojbectInStoreMgr.findObject(this, this.dataStore); + return obj.getInstallPath(); + } + public long getVolumeId() { return volumeVO.getId(); } @@ -174,11 +181,6 @@ public class VolumeObject implements VolumeInfo { return DataObjectType.VOLUME; } - @Override - public DiskFormat getFormat() { - // TODO Auto-generated method stub - return null; - } @Override public void processEvent( @@ -388,7 +390,7 @@ public class VolumeObject implements VolumeInfo { this.volumeStoreDao.update(volStore.getId(), volStore); } } - + this.processEvent(event); } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 4e39ddebf09..215973363bc 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -70,7 +70,6 @@ import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; @@ -643,9 +642,9 @@ public class VolumeServiceImpl implements VolumeService { AsyncCallFuture future = new AsyncCallFuture(); DataObject volumeOnStore = store.create(volume); - + volumeOnStore.processEvent(Event.CreateOnlyRequested); - + CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)) @@ -657,7 +656,7 @@ public class VolumeServiceImpl implements VolumeService { protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); - + VolumeObject vo = (VolumeObject)context.volume; if (result.isFailed()) { vo.processEvent(Event.OperationFailed); @@ -813,7 +812,8 @@ public class VolumeServiceImpl implements VolumeService { } s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName()); //TODO: pass a callback later - downloadMonitor.downloadVolumeToStorage(this.volFactory.getVolume(volumeHost.getVolumeId()), store, volumeHost.getDownloadUrl(), volumeHost.getChecksum(), volumeHost.getFormat(), null); + VolumeInfo vol = this.volFactory.getVolume(volumeHost.getVolumeId()); + this.createVolumeAsync(vol, store); } } @@ -843,12 +843,12 @@ public class VolumeServiceImpl implements VolumeService { return null; } - + @Override public SnapshotInfo takeSnapshot(VolumeInfo volume) { VolumeObject vol = (VolumeObject)volume; vol.stateTransit(Volume.Event.SnapshotRequested); - + SnapshotInfo snapshot = null; try { snapshot = this.snapshotMgr.takeSnapshot(volume); @@ -861,7 +861,7 @@ public class VolumeServiceImpl implements VolumeService { vol.stateTransit(Volume.Event.OperationFailed); } } - + return snapshot; } diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java index a90ea9e10eb..810f33020cf 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java @@ -16,6 +16,9 @@ // under the License. package com.cloud.agent.manager; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; + import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.AttachVolumeAnswer; @@ -41,8 +44,6 @@ import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DestroyCommand; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index d8a3e510521..a0897b87f22 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -48,8 +48,6 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ListVolumeAnswer; @@ -81,6 +79,9 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine.State; + +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.api.to.NfsTO; diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index c234cc5cb2e..f67a818dc76 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -34,6 +34,9 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.VirtualMachine.State; + +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index c2e4c9c27bd..382ae44d7c4 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -34,6 +34,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; @@ -45,19 +46,15 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; -import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -166,13 +163,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { if (data.getType() == DataObjectType.TEMPLATE) { - TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); + _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { - VolumeObject volInfo = (VolumeObject)data; - RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); + _downloadMonitor.downloadVolumeToStorage(data, caller); } } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 31e2fdd6d58..c92ea26152d 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -36,6 +36,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; @@ -48,7 +49,6 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; -import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -59,10 +59,8 @@ import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; -import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; @@ -71,13 +69,11 @@ import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; @@ -179,13 +175,9 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { if (data.getType() == DataObjectType.TEMPLATE) { - TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); + _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { - VolumeObject volInfo = (VolumeObject)data; - RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); + _downloadMonitor.downloadVolumeToStorage(data, caller); } } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 4f83d4b30a7..10310773bc5 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -48,7 +48,6 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; -import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -58,26 +57,21 @@ import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; -import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; -import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.DataStoreRole; import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeHostVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; @@ -172,13 +166,9 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { if (data.getType() == DataObjectType.TEMPLATE) { - TemplateObject tData = (TemplateObject)data; - _downloadMonitor.downloadTemplateToStorage(tData, tData.getDataStore(), caller); + _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { - VolumeObject volInfo = (VolumeObject)data; - RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); - _downloadMonitor.downloadVolumeToStorage(volInfo, volInfo.getDataStore(), payload.getUrl(), - payload.getChecksum(), ImageFormat.valueOf(payload.getFormat().toUpperCase()), caller); + _downloadMonitor.downloadVolumeToStorage(data, caller); } } diff --git a/server/src/com/cloud/storage/download/DownloadAbandonedState.java b/server/src/com/cloud/storage/download/DownloadAbandonedState.java index ef053ce2737..187683b7e73 100644 --- a/server/src/com/cloud/storage/download/DownloadAbandonedState.java +++ b/server/src/com/cloud/storage/download/DownloadAbandonedState.java @@ -16,8 +16,9 @@ // under the License. package com.cloud.storage.download; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; + import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; public class DownloadAbandonedState extends DownloadInactiveState { diff --git a/server/src/com/cloud/storage/download/DownloadActiveState.java b/server/src/com/cloud/storage/download/DownloadActiveState.java index 09d103ef27c..44efa4bd4f4 100644 --- a/server/src/com/cloud/storage/download/DownloadActiveState.java +++ b/server/src/com/cloud/storage/download/DownloadActiveState.java @@ -16,10 +16,10 @@ // under the License. package com.cloud.storage.download; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; import org.apache.log4j.Level; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; public abstract class DownloadActiveState extends DownloadState { diff --git a/server/src/com/cloud/storage/download/DownloadCompleteState.java b/server/src/com/cloud/storage/download/DownloadCompleteState.java index 6e8edcbf691..ea2ae9107f6 100644 --- a/server/src/com/cloud/storage/download/DownloadCompleteState.java +++ b/server/src/com/cloud/storage/download/DownloadCompleteState.java @@ -16,7 +16,8 @@ // under the License. package com.cloud.storage.download; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; + import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; public class DownloadCompleteState extends DownloadInactiveState { diff --git a/server/src/com/cloud/storage/download/DownloadErrorState.java b/server/src/com/cloud/storage/download/DownloadErrorState.java index e5c88205309..aedb56e7250 100644 --- a/server/src/com/cloud/storage/download/DownloadErrorState.java +++ b/server/src/com/cloud/storage/download/DownloadErrorState.java @@ -16,10 +16,10 @@ // under the License. package com.cloud.storage.download; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; import org.apache.log4j.Level; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; public class DownloadErrorState extends DownloadInactiveState { diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index af5d771aef1..001b45dc1c4 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -34,6 +34,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; import org.apache.log4j.Level; import org.apache.log4j.Logger; @@ -46,10 +50,6 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; -import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; import com.cloud.host.Host; diff --git a/server/src/com/cloud/storage/download/DownloadMonitor.java b/server/src/com/cloud/storage/download/DownloadMonitor.java index 42fb9d277b1..5b8f9a087b1 100644 --- a/server/src/com/cloud/storage/download/DownloadMonitor.java +++ b/server/src/com/cloud/storage/download/DownloadMonitor.java @@ -17,11 +17,9 @@ package com.cloud.storage.download; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.component.Manager; /** @@ -31,8 +29,8 @@ import com.cloud.utils.component.Manager; public interface DownloadMonitor extends Manager{ - public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback); + public void downloadTemplateToStorage(DataObject template, AsyncCompletionCallback callback); - public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, AsyncCompletionCallback callback); + public void downloadVolumeToStorage(DataObject volume, AsyncCompletionCallback callback); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index d5d01a6a8ff..09dbae3dadd 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -33,7 +33,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; +import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -43,22 +48,12 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; -import com.cloud.agent.Listener; -import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadCommand.Proxy; -import com.cloud.agent.api.storage.DownloadCommand.ResourceType; -import com.cloud.agent.api.storage.DownloadProgressCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; -import com.cloud.agent.manager.Commands; -import com.cloud.alert.AlertManager; +import com.cloud.agent.api.storage.Proxy; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.host.HostVO; +import com.cloud.storage.RegisterVolumePayload; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.StorageManager; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -68,20 +63,15 @@ import com.cloud.storage.VolumeHostVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.swift.SwiftManager; import com.cloud.storage.template.TemplateConstants; -import com.cloud.template.TemplateManager; import com.cloud.template.VirtualMachineTemplate; -import com.cloud.user.AccountManager; -import com.cloud.user.ResourceLimitService; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; -import com.cloud.utils.db.DB; import com.cloud.utils.db.JoinBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; -import com.cloud.vm.UserVmManager; -import com.cloud.vm.dao.UserVmDao; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; @Component @Local(value = { DownloadMonitor.class }) @@ -175,14 +165,13 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor return (downloadsInProgress.size() == 0); } - private void initiateTemplateDownload(DataObject template, DataStore store, AsyncCompletionCallback callback) { + private void initiateTemplateDownload(DataObject template, AsyncCompletionCallback callback) { boolean downloadJobExists = false; TemplateDataStoreVO vmTemplateStore = null; + DataStore store = template.getDataStore(); vmTemplateStore = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); if (vmTemplateStore == null) { - // This method can be invoked other places, for example, - // handleTemplateSync, in that case, vmTemplateStore may be null vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUri()); _vmTemplateStoreDao.persist(vmTemplateStore); @@ -194,7 +183,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (vmTemplateStore != null) { start(); VirtualMachineTemplate tmpl = this._templateDao.findById(template.getId()); - DownloadCommand dcmd = new DownloadCommand(store.getTO(), tmpl, maxTemplateSizeInBytes); + DownloadCommand dcmd = new DownloadCommand((TemplateObjectTO)(template.getTO()), maxTemplateSizeInBytes); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, vmTemplateStore.getJobId(), RequestType.GET_OR_RESTART); @@ -238,20 +227,26 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor @Override - public void downloadTemplateToStorage(DataObject template, DataStore store, AsyncCompletionCallback callback) { + public void downloadTemplateToStorage(DataObject template, AsyncCompletionCallback callback) { long templateId = template.getId(); + DataStore store = template.getDataStore(); if (isTemplateUpdateable(templateId, store.getId())) { if (template != null && template.getUri() != null) { - initiateTemplateDownload(template, store, callback); + initiateTemplateDownload(template, callback); } } } @Override - public void downloadVolumeToStorage(DataObject volume, DataStore store, String url, String checkSum, ImageFormat format, - AsyncCompletionCallback callback) { + public void downloadVolumeToStorage(DataObject volume, AsyncCompletionCallback callback) { boolean downloadJobExists = false; VolumeDataStoreVO volumeHost = null; + DataStore store = volume.getDataStore(); + VolumeInfo volInfo = (VolumeInfo)volume; + RegisterVolumePayload payload = (RegisterVolumePayload)volInfo.getpayload(); + String url = payload.getUrl(); + String checkSum = payload.getChecksum(); + ImageFormat format = ImageFormat.valueOf(payload.getFormat()); volumeHost = _volumeStoreDao.findByStoreVolume(store.getId(), volume.getId()); if (volumeHost == null) { @@ -266,7 +261,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (volumeHost != null) { start(); Volume vol = this._volumeDao.findById(volume.getId()); - DownloadCommand dcmd = new DownloadCommand(store.getTO(), vol, maxVolumeSizeInBytes, checkSum, url, format); + DownloadCommand dcmd = new DownloadCommand((VolumeObjectTO)(volume.getTO()), maxVolumeSizeInBytes, checkSum, url, format); dcmd.setProxy(getHttpProxy()); if (downloadJobExists) { dcmd = new DownloadProgressCommand(dcmd, volumeHost.getJobId(), RequestType.GET_OR_RESTART); diff --git a/server/src/com/cloud/storage/download/NotDownloadedState.java b/server/src/com/cloud/storage/download/NotDownloadedState.java index 77521731769..e10feb312d4 100644 --- a/server/src/com/cloud/storage/download/NotDownloadedState.java +++ b/server/src/com/cloud/storage/download/NotDownloadedState.java @@ -16,7 +16,8 @@ // under the License. package com.cloud.storage.download; -import com.cloud.agent.api.storage.DownloadProgressCommand.RequestType; +import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; + import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; public class NotDownloadedState extends DownloadActiveState { diff --git a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java index 02463d2f7dc..29e6a055b81 100644 --- a/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java +++ b/server/src/com/cloud/storage/resource/DummySecondaryStorageResource.java @@ -24,6 +24,8 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -39,8 +41,6 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.DownloadCommand; -import com.cloud.agent.api.storage.DownloadProgressCommand; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.resource.ServerResource; From 0c6e87c701fcf08fad2fbb62d618be339d27eeca Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 3 May 2013 09:45:31 -0700 Subject: [PATCH 092/303] download template to primary storage works now --- .../cloudstack/storage/to/VolumeObjectTO.java | 2 +- .../storage/test/CloudStackTestNGBase.java | 14 ++++++++++++-- .../test/DirectAgentManagerSimpleImpl.java | 12 ++++++++++-- .../storage/test/volumeServiceTest.java | 16 ---------------- .../cloudstack/storage/volume/VolumeObject.java | 7 ++++++- .../storage/volume/VolumeServiceImpl.java | 2 +- 6 files changed, 30 insertions(+), 23 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 0b8846941ba..5e6ca2b79cb 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -41,7 +41,7 @@ public class VolumeObjectTO implements DataTO { public VolumeObjectTO(VolumeInfo volume) { this.uuid = volume.getUuid(); - this.path = volume.getUri(); + this.path = volume.getPath(); this.accountId = volume.getAccountId(); if (volume.getDataStore() != null) { this.dataStore = volume.getDataStore().getTO(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 40267a70c8a..4ea3d3ff85f 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -36,6 +36,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String localStorageUuid; private String primaryStorageUrl; private String secondaryStorage; + private String imageInstallPath; private Transaction txn; private String s3AccessKey; @@ -66,13 +67,14 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { } @BeforeMethod(alwaysRun = true) + @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps"}) + "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path"}) protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid, String primaryStorage, String secondaryStorage, String s3_accessKey, String s3_secretKey, String s3_endpoint, String s3_template_bucket, - String s3_usehttps) { + String s3_usehttps, String imageInstallPath) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -80,6 +82,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.templateUrl = templateUrl; this.localStorageUuid = localStorageUuid; this.primaryStorageUrl = primaryStorage; + this.imageInstallPath = imageInstallPath; this.setSecondaryStorage(secondaryStorage); // set S3 parameters this.s3AccessKey = s3_accessKey; @@ -125,6 +128,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.secondaryStorage = secondaryStorage; } + public String getS3AccessKey() { return s3AccessKey; } @@ -145,6 +149,12 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { return s3UseHttps; } + public String getImageInstallPath() { + return imageInstallPath; + } + public void setImageInstallPath(String imageInstallPath) { + this.imageInstallPath = imageInstallPath; + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index 6941ff8cfdc..127c0e30a91 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -79,8 +79,16 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa @Override public Answer easySend(Long hostId, Command cmd) { - // TODO Auto-generated method stub - return null; + try { + return this.send(hostId, cmd); + } catch (AgentUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (OperationTimedoutException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; } protected void loadResource(Long hostId) { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 919ca35aefb..2152b2e64eb 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -183,22 +183,6 @@ public class volumeServiceTest extends CloudStackTestNGBase { imageStore.setUuid(UUID.randomUUID().toString()); imageStore = imageStoreDao.persist(imageStore); - //primaryStore = createPrimaryDataStore(); - - //CreateVolumeAnswer createVolumeFromImageAnswer = new CreateVolumeAnswer(UUID.randomUUID().toString()); - - /*try { - Mockito.when(agentMgr.send(Mockito.anyLong(), Mockito.any(CreateVolumeFromBaseImageCommand.class))).thenReturn(createVolumeFromImageAnswer); - } catch (AgentUnavailableException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (OperationTimedoutException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - }*/ - - - //Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 31a2e6ffa57..d1d7b8d6b0f 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -244,7 +244,12 @@ public class VolumeObject implements VolumeInfo { @Override public String getPath() { - return this.volumeVO.getPath(); + if (this.dataStore.getRole() == DataStoreRole.Primary) { + return this.volumeVO.getPath(); + } else { + DataObjectInStore objInStore = this.ojbectInStoreMgr.findObject(this, dataStore); + return objInStore.getInstallPath(); + } } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 215973363bc..07a5430aa6d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -376,7 +376,7 @@ public class VolumeServiceImpl implements VolumeService { templateOnPrimaryStoreObj.processEvent(Event.OperationFailed); VolumeApiResult result = new VolumeApiResult(volume); result.setResult(e.toString()); - caller.complete(result); + future.complete(result); } return; } From fc74d766960db523296ab886f71c5c0804c3ee17 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 3 May 2013 09:53:06 -0700 Subject: [PATCH 093/303] add volume test case --- .../cloudstack/storage/test/VolumeTest.java | 298 ++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java new file mode 100644 index 00000000000..cceceda35ba --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -0,0 +1,298 @@ +/* + * 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.test; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.RemoteHostEndPoint; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +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.apache.cloudstack.storage.volume.db.VolumeDao2; +import org.apache.cloudstack.storage.volume.db.VolumeVO; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.testng.annotations.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.host.Host; +import com.cloud.host.Host.Type; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.org.Cluster.ClusterType; +import com.cloud.org.Managed.ManagedState; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.utils.component.ComponentContext; + +@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +public class VolumeTest extends CloudStackTestNGBase { + @Inject + ImageStoreDao imageStoreDao; + ImageStoreVO imageStore; + Long dcId; + Long clusterId; + Long podId; + HostVO host; + String primaryName = "my primary data store"; + DataStore primaryStore; + @Inject + HostDao hostDao; + @Inject + TemplateService imageService; + @Inject + VolumeService volumeService; + @Inject + VMTemplateDao imageDataDao; + @Inject + VolumeDao2 volumeDao; + @Inject + HostPodDao podDao; + @Inject + ClusterDao clusterDao; + @Inject + DataCenterDao dcDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + @Inject + DataStoreProviderManager dataStoreProviderMgr; + @Inject + TemplateDataStoreDao templateStoreDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + PrimaryDataStoreDao primaryDataStoreDao; + @Inject + AgentManager agentMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + ResourceManager resourceMgr; + @Inject + VolumeDataFactory volFactory; + @Inject + EndPointSelector epSelector; + long primaryStoreId; + VMTemplateVO image; + String imageStoreName = "testImageStore"; + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + + host = hostDao.findByGuid(this.getHostGuid()); + if (host != null) { + dcId = host.getDataCenterId(); + clusterId = host.getClusterId(); + podId = host.getPodId(); + imageStore = this.imageStoreDao.findByName(imageStoreName); + } else { + //create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", + null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + //create pod + + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); + pod = podDao.persist(pod); + podId = pod.getId(); + //create xen cluster + ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); + cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setClusterType(ClusterType.CloudManaged); + cluster.setManagedState(ManagedState.Managed); + cluster = clusterDao.persist(cluster); + clusterId = cluster.getId(); + //create xen host + + host = new HostVO(this.getHostGuid()); + host.setName("devcloud xen host"); + host.setType(Host.Type.Routing); + host.setPrivateIpAddress(this.getHostIp()); + host.setDataCenterId(dc.getId()); + host.setVersion("6.0.1"); + host.setAvailable(true); + host.setSetup(true); + host.setPodId(podId); + host.setLastPinged(0); + host.setResourceState(ResourceState.Enabled); + host.setHypervisorType(HypervisorType.XenServer); + host.setClusterId(cluster.getId()); + + host = hostDao.persist(host); + + imageStore = new ImageStoreVO(); + imageStore.setName(imageStoreName); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore.setProtocol("nfs"); + imageStore = imageStoreDao.persist(imageStore); + } + + image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + + image = imageDataDao.persist(image); + + /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); + + templateStore.setDataStoreId(imageStore.getId()); + templateStore.setDownloadPercent(100); + templateStore.setDownloadState(Status.DOWNLOADED); + templateStore.setDownloadUrl(imageStore.getUrl()); + templateStore.setInstallPath(this.getImageInstallPath()); + templateStore.setTemplateId(image.getId()); + templateStoreDao.persist(templateStore);*/ + + + DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); + TemplateInfo template = templateFactory.getTemplate(image.getId()); + DataObject templateOnStore = store.create(template); + TemplateObjectTO to = new TemplateObjectTO(); + to.setPath(this.getImageInstallPath()); + CopyCmdAnswer answer = new CopyCmdAnswer(to); + templateOnStore.processEvent(Event.CreateOnlyRequested); + templateOnStore.processEvent(Event.OperationSuccessed, answer); + + + } + + @Override + protected void injectMockito() { + List hosts = new ArrayList(); + hosts.add(this.host); + Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(new LocalHostEndpoint()); + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); + } + + public DataStore createPrimaryDataStore() { + try { + String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString(); + List pools = primaryDataStoreDao.findPoolByName(this.primaryName); + if (pools.size() > 0) { + return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); + } + + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); + Map params = new HashMap(); + URI uri = new URI(this.getPrimaryStorageUrl()); + params.put("url", this.getPrimaryStorageUrl()); + params.put("server", uri.getHost()); + params.put("path", uri.getPath()); + params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); + params.put("zoneId", dcId); + params.put("clusterId", clusterId); + params.put("name", this.primaryName); + params.put("port", 1); + params.put("podId", this.podId); + params.put("roles", DataStoreRole.Primary.toString()); + params.put("uuid", uuid); + params.put("providerName", String.valueOf(provider.getName())); + + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + DataStore store = lifeCycle.initialize(params); + ClusterScope scope = new ClusterScope(clusterId, podId, dcId); + lifeCycle.attachCluster(store, scope); + return store; + } catch (Exception e) { + return null; + } + } + + private VolumeVO createVolume(Long templateId, long dataStoreId) { + VolumeVO volume = new VolumeVO(1000, new RootDisk().toString(), UUID.randomUUID().toString(), templateId); + //volume.setPoolId(dataStoreId); + volume = volumeDao.persist(volume); + return volume; + } + + @Test + public void testCopyBaseImage() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId())); + } +} From df7a56d63f674b3a92b3c521593d79bc86d12fb5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 3 May 2013 10:01:23 -0700 Subject: [PATCH 094/303] Removed redundant getInstallPath to use getPath in VolumeInfo. --- .../cloudstack/engine/subsystem/api/storage/VolumeInfo.java | 1 - .../apache/cloudstack/storage/command/DownloadCommand.java | 1 + .../org/apache/cloudstack/storage/volume/VolumeObject.java | 5 ----- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index b02eaf1866c..7165f370bac 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -28,5 +28,4 @@ public interface VolumeInfo extends DataObject, Volume { public HypervisorType getHypervisorType(); public Long getLastPoolId(); public String getAttachedVmName(); - public String getInstallPath(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java index d70c78623f1..5388f0a9ebd 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java @@ -87,6 +87,7 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal super(volume.getName(), url, format, volume.getAccountId()); this.checksum = checkSum; this.id = volume.getVolumeId(); + this.installPath = volume.getPath(); this._store = volume.getDataStore(); this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceType = ResourceType.VOLUME; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index d1d7b8d6b0f..ffac68e3af6 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -120,11 +120,6 @@ public class VolumeObject implements VolumeInfo { return volumeVO.getSize(); } - @Override - public String getInstallPath() { - DataObjectInStore obj = ojbectInStoreMgr.findObject(this, this.dataStore); - return obj.getInstallPath(); - } public long getVolumeId() { return volumeVO.getId(); From 23db72d8b40903e306a3e5953b7e39155829d81d Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 3 May 2013 14:59:13 -0700 Subject: [PATCH 095/303] S3 template download test is working except state transition part. --- .../LocalNfsSecondaryStorageResource.java | 4 - .../resource/NfsSecondaryStorageResource.java | 4 +- .../storage/template/DownloadManagerImpl.java | 145 ++++++++++-------- .../template/S3TemplateDownloader.java | 37 ++++- .../MockLocalNfsSecondaryStorageResource.java | 103 +++++++++++++ .../storage/test/S3TemplateTest.java | 8 +- .../integration-test/test/resource/testng.xml | 12 +- .../cloudstack/storage/LocalHostEndpoint.java | 8 + 8 files changed, 237 insertions(+), 84 deletions(-) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index 06933cc4068..a2cf757b432 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -32,10 +32,6 @@ import com.cloud.utils.exception.CloudRuntimeException; public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { - public LocalNfsSecondaryStorageResource(){ - _dlMgr = new DownloadManagerImpl(); - } - @Override public Answer executeRequest(Command cmd) { if (cmd instanceof DownloadSystemTemplateCommand){ diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 47d5ce7bcba..0345f6b0e90 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -144,8 +144,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S boolean _inSystemVM = false; boolean _sslCopy = false; - DownloadManager _dlMgr; - UploadManager _upldMgr; + protected DownloadManager _dlMgr; + protected UploadManager _upldMgr; private String _configSslScr; private String _configAuthScr; private String _configIpFirewallScr; diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 02a62568856..cd6165d1e3b 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -116,7 +116,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private final long id; private final ResourceType resourceType; - public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, ResourceType resourceType) { + public DownloadJob(TemplateDownloader td, String jobId, long id, String tmpltName, ImageFormat format, boolean hvm, Long accountId, + String descr, String cksum, String installPathPrefix, ResourceType resourceType) { super(); this.td = td; this.jobId = jobId; @@ -239,8 +240,14 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private int installTimeoutPerGig = 180 * 60 * 1000; private boolean _sslCopy; + + public void setThreadPool(ExecutorService threadPool) { + this.threadPool = threadPool; + } + /** - * Get notified of change of job status. Executed in context of downloader thread + * Get notified of change of job status. Executed in context of downloader + * thread * * @param jobId * the id of the job @@ -255,7 +262,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } TemplateDownloader td = dj.getTemplateDownloader(); s_logger.info("Download Completion for jobId: " + jobId + ", status=" + status); - s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" + td.getDownloadPercent()); + s_logger.info("local: " + td.getDownloadLocalPath() + ", bytes=" + td.getDownloadedBytes() + ", error=" + td.getDownloadError() + ", pct=" + + td.getDownloadPercent()); switch (status) { case ABORTED: @@ -276,7 +284,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager break; case DOWNLOAD_FINISHED: if (!(td instanceof S3TemplateDownloader)) { - // we currently only create template.properties for NFS by running some post download script + // we currently only create template.properties for NFS by + // running some post download script td.setDownloadError("Download success, starting install "); String result = postDownload(jobId); if (result != null) { @@ -304,21 +313,20 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager try { digest = MessageDigest.getInstance("MD5"); is = new FileInputStream(f); - while( (read = is.read(buffer)) > 0) { + while ((read = is.read(buffer)) > 0) { digest.update(buffer, 0, read); } byte[] md5sum = digest.digest(); BigInteger bigInt = new BigInteger(1, md5sum); - checksum = String.format("%032x",bigInt); + checksum = String.format("%032x", bigInt); return checksum; - }catch(IOException e) { + } catch (IOException e) { return null; - }catch (NoSuchAlgorithmException e) { + } catch (NoSuchAlgorithmException e) { return null; - } - finally { + } finally { try { - if(is != null) + if (is != null) is.close(); } catch (IOException e) { return null; @@ -327,7 +335,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } /** - * Post download activity (install and cleanup). Executed in context of downloader thread + * Post download activity (install and cleanup). Executed in context of + * downloader thread * * @throws IOException */ @@ -337,12 +346,13 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String resourcePath = null; ResourceType resourceType = dnld.getResourceType(); - // once template path is set, remove the parent dir so that the template is installed with a relative path + // once template path is set, remove the parent dir so that the template + // is installed with a relative path String finalResourcePath = ""; - if (resourceType == ResourceType.TEMPLATE){ + if (resourceType == ResourceType.TEMPLATE) { finalResourcePath += _templateDir + File.separator + dnld.getAccountId() + File.separator + dnld.getId() + File.separator; resourcePath = dnld.getInstallPathPrefix() + dnld.getAccountId() + File.separator + dnld.getId() + File.separator;// dnld.getTmpltName(); - }else { + } else { finalResourcePath += _volumeDir + File.separator + dnld.getId() + File.separator; resourcePath = dnld.getInstallPathPrefix() + dnld.getId() + File.separator;// dnld.getTmpltName(); } @@ -375,7 +385,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager // add options common to ISO and template String extension = dnld.getFormat().getFileExtension(); String templateName = ""; - if( extension.equals("iso")) { + if (extension.equals("iso")) { templateName = jobs.get(jobId).getTmpltName().trim().replace(" ", "_"); } else { templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString(); @@ -404,9 +414,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager // Set permissions for template/volume.properties String propertiesFile = resourcePath; - if (resourceType == ResourceType.TEMPLATE){ + if (resourceType == ResourceType.TEMPLATE) { propertiesFile += "/template.properties"; - }else{ + } else { propertiesFile += "/volume.properties"; } File templateProperties = new File(propertiesFile); @@ -461,7 +471,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } @Override - public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, + String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); @@ -489,15 +500,15 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return jobId; } - @Override - public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, + String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); String tmpDir = ""; - if(resourceType == ResourceType.TEMPLATE){ + if (resourceType == ResourceType.TEMPLATE) { tmpDir = installPathPrefix + File.separator + accountId + File.separator + id; - }else { + } else { tmpDir = installPathPrefix + File.separator + id; } @@ -507,10 +518,10 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager s_logger.warn("Unable to create " + tmpDir); return "Unable to create " + tmpDir; } - // TO DO - define constant for volume properties. - File file = ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : - _storage.getFile(tmpDir + File.separator + "volume.properties"); - if ( file.exists() ) { + // TO DO - define constant for volume properties. + File file = ResourceType.TEMPLATE == resourceType ? _storage.getFile(tmpDir + File.separator + TemplateLocation.Filename) : _storage + .getFile(tmpDir + File.separator + "volume.properties"); + if (file.exists()) { file.delete(); } @@ -528,7 +539,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager TemplateDownloader td; if ((uri != null) && (uri.getScheme() != null)) { if (uri.getScheme().equalsIgnoreCase("http") || uri.getScheme().equalsIgnoreCase("https")) { - td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, resourceType); + td = new HttpTemplateDownloader(_storage, url, tmpDir, new Completion(jobId), maxTemplateSizeInBytes, user, password, proxy, + resourceType); } else if (uri.getScheme().equalsIgnoreCase("file")) { td = new LocalTemplateDownloader(_storage, url, tmpDir, maxTemplateSizeInBytes, new Completion(jobId)); } else if (uri.getScheme().equalsIgnoreCase("scp")) { @@ -633,16 +645,16 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return convertStatus(getDownloadStatus(jobId)); } - @Override public DownloadAnswer handleDownloadCommand(SecondaryStorageResource resource, DownloadCommand cmd) { ResourceType resourceType = cmd.getResourceType(); if (cmd instanceof DownloadProgressCommand) { - return handleDownloadProgressCmd( resource, (DownloadProgressCommand) cmd); + return handleDownloadProgressCmd(resource, (DownloadProgressCommand) cmd); } if (cmd.getUrl() == null) { - return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); + return new DownloadAnswer(resourceType.toString() + " is corrupted on storage due to an invalid url , cannot download", + VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } if (cmd.getName() == null) { @@ -657,21 +669,23 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager user = cmd.getAuth().getUserName(); password = new String(cmd.getAuth().getPassword()); } - //TO DO - Define Volume max size as well - long maxDownloadSizeInBytes = (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd.getMaxDownloadSizeInBytes()); + // TO DO - Define Volume max size as well + long maxDownloadSizeInBytes = (cmd.getMaxDownloadSizeInBytes() == null) ? TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES : (cmd + .getMaxDownloadSizeInBytes()); String jobId = null; - if (dstore instanceof S3TO){ - jobId = downloadS3Template((S3TO)dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); - } - else{ - jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + if (dstore instanceof S3TO) { + jobId = downloadS3Template((S3TO) dstore, cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), + cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + } else { + jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), + cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } sleep(); if (jobId == null) { return new DownloadAnswer("Internal Error", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } - return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), getInstallPath(jobId), - getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId)); + return new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), + getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplateSize(jobId), getDownloadCheckSum(jobId)); } private void sleep() { @@ -712,8 +726,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager break; case PURGE: td.stopDownload(); - answer = new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), getDownloadLocalPath(jobId), - getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), getDownloadCheckSum(jobId)); + answer = new DownloadAnswer(jobId, getDownloadPct(jobId), getDownloadError(jobId), getDownloadStatus2(jobId), + getDownloadLocalPath(jobId), getInstallPath(jobId), getDownloadTemplateSize(jobId), getDownloadTemplatePhysicalSize(jobId), + getDownloadCheckSum(jobId)); jobs.remove(jobId); return answer; default: @@ -741,7 +756,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } - private List listVolumes(String rootdir) { List result = new ArrayList(); @@ -754,8 +768,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return result; } - - private List listTemplates(String rootdir) { List result = new ArrayList(); @@ -773,7 +785,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager Map result = new HashMap(); String templateDir = rootDir + File.separator + _templateDir; - if (! _storage.exists(templateDir)) { + if (!_storage.exists(templateDir)) { _storage.mkdirs(templateDir); } @@ -784,7 +796,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager try { if (!loc.load()) { s_logger.warn("Post download installation was not completed for " + path); - //loc.purge(); + // loc.purge(); _storage.cleanup(path, templateDir); continue; } @@ -798,8 +810,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager if ((tInfo.size == tInfo.physicalSize) && (tInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) { try { Processor processor = _processors.get("VMDK Processor"); - VmdkProcessor vmdkProcessor = (VmdkProcessor)processor; - long vSize = vmdkProcessor.getTemplateVirtualSize(path, tInfo.installPath.substring(tInfo.installPath.lastIndexOf(File.separator) + 1)); + VmdkProcessor vmdkProcessor = (VmdkProcessor) processor; + long vSize = vmdkProcessor.getTemplateVirtualSize(path, + tInfo.installPath.substring(tInfo.installPath.lastIndexOf(File.separator) + 1)); tInfo.size = vSize; loc.updateVirtualSize(vSize); loc.save(); @@ -830,7 +843,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager Map result = new HashMap(); String volumeDir = rootDir + File.separator + _volumeDir; - if (! _storage.exists(volumeDir)) { + if (!_storage.exists(volumeDir)) { _storage.mkdirs(volumeDir); } @@ -841,7 +854,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager try { if (!loc.load()) { s_logger.warn("Post download installation was not completed for " + path); - //loc.purge(); + // loc.purge(); _storage.cleanup(path, volumeDir); continue; } @@ -855,8 +868,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager if ((vInfo.size == vInfo.physicalSize) && (vInfo.installPath.endsWith(ImageFormat.OVA.getFileExtension()))) { try { Processor processor = _processors.get("VMDK Processor"); - VmdkProcessor vmdkProcessor = (VmdkProcessor)processor; - long vSize = vmdkProcessor.getTemplateVirtualSize(path, vInfo.installPath.substring(vInfo.installPath.lastIndexOf(File.separator) + 1)); + VmdkProcessor vmdkProcessor = (VmdkProcessor) processor; + long vSize = vmdkProcessor.getTemplateVirtualSize(path, + vInfo.installPath.substring(vInfo.installPath.lastIndexOf(File.separator) + 1)); vInfo.size = vSize; loc.updateVirtualSize(vSize); loc.save(); @@ -929,7 +943,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String value = null; - _storage = (StorageLayer)params.get(StorageLayer.InstanceConfigKey); + _storage = (StorageLayer) params.get(StorageLayer.InstanceConfigKey); if (_storage == null) { value = (String) params.get(StorageLayer.ClassConfigKey); if (value == null) { @@ -948,12 +962,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager throw new ConfigurationException("Unable to instantiate " + value); } } - String useSsl = (String)params.get("sslcopy"); + String useSsl = (String) params.get("sslcopy"); if (useSsl != null) { _sslCopy = Boolean.parseBoolean(useSsl); } - String inSystemVM = (String)params.get("secondary.storage.vm"); + String inSystemVM = (String) params.get("secondary.storage.vm"); if (inSystemVM != null && "true".equalsIgnoreCase(inSystemVM)) { s_logger.info("DownloadManager: starting additional services since we are inside system vm"); startAdditionalServices(); @@ -1032,12 +1046,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager Script command = new Script("/bin/bash", s_logger); String intf = "eth1"; command.add("-c"); - command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" + - "iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;"); + command.add("iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "80" + " -j REJECT;" + + "iptables -A OUTPUT -o " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j REJECT;"); String result = command.execute(); if (result != null) { - s_logger.warn("Error in blocking outgoing to port 80/443 err=" + result ); + s_logger.warn("Error in blocking outgoing to port 80/443 err=" + result); return; } } @@ -1064,19 +1078,19 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager command.add("if [ -d /etc/apache2 ] ; then service apache2 stop; else service httpd stop; fi "); String result = command.execute(); if (result != null) { - s_logger.warn("Error in stopping httpd service err=" + result ); + s_logger.warn("Error in stopping httpd service err=" + result); } String port = Integer.toString(TemplateConstants.DEFAULT_TMPLT_COPY_PORT); String intf = TemplateConstants.DEFAULT_TMPLT_COPY_INTF; command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" + - "iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;"); + command.add("iptables -I INPUT -i " + intf + " -p tcp -m state --state NEW -m tcp --dport " + port + " -j ACCEPT;" + "iptables -I INPUT -i " + + intf + " -p tcp -m state --state NEW -m tcp --dport " + "443" + " -j ACCEPT;"); result = command.execute(); if (result != null) { - s_logger.warn("Error in opening up httpd port err=" + result ); + s_logger.warn("Error in opening up httpd port err=" + result); return; } @@ -1085,7 +1099,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager command.add("if [ -d /etc/apache2 ] ; then service apache2 start; else service httpd start; fi "); result = command.execute(); if (result != null) { - s_logger.warn("Error in starting httpd service err=" + result ); + s_logger.warn("Error in starting httpd service err=" + result); return; } command = new Script("mkdir", s_logger); @@ -1093,10 +1107,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager command.add("/var/www/html/copy/template"); result = command.execute(); if (result != null) { - s_logger.warn("Error in creating directory =" + result ); + s_logger.warn("Error in creating directory =" + result); return; } } - } diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index 84b2b10f847..eac9bbf6922 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -40,14 +40,18 @@ import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpMethodRetryHandler; +import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.NoHttpResponseException; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpMethodParams; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import com.amazonaws.AmazonClientException; +import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.ProgressEvent; import com.amazonaws.services.s3.model.ProgressListener; @@ -176,8 +180,7 @@ public class S3TemplateDownloader implements TemplateDownloader { port = 80; } - URL urlObj = new URL(url); - this.fileName = urlObj.getFile(); + this.fileName = StringUtils.substringAfterLast(url, "/"); String host = uri.getHost(); try { @@ -199,10 +202,7 @@ public class S3TemplateDownloader implements TemplateDownloader { } catch (URISyntaxException use) { s_logger.warn("Failed uri syntax check: " + use.getMessage()); throw new IllegalArgumentException(use.getMessage()); - } catch (MalformedURLException e) { - s_logger.warn("Failed url syntax check: " + e.getMessage()); - throw new IllegalArgumentException(e.getMessage()); - } + } } @Override @@ -215,8 +215,17 @@ public class S3TemplateDownloader implements TemplateDownloader { default: } + + int bytes=0; try { + // execute get method + int responseCode = HttpStatus.SC_OK; + if ((responseCode = client.executeMethod(request)) != HttpStatus.SC_OK) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = " HTTP Server returned " + responseCode + " (expected 200 OK) "; + return 0; //FIXME: retry? + } // get the total size of file Header contentLengthHeader = request.getResponseHeader("Content-Length"); boolean chunked = false; @@ -277,14 +286,23 @@ public class S3TemplateDownloader implements TemplateDownloader { if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) { s_logger.info("download completed"); status = TemplateDownloader.Status.DOWNLOAD_FINISHED; - } else { + } else if (progressEvent.getEventCode() == ProgressEvent.FAILED_EVENT_CODE){ + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + } else if (progressEvent.getEventCode() == ProgressEvent.CANCELED_EVENT_CODE){ + status = TemplateDownloader.Status.ABORTED; + } else{ status = TemplateDownloader.Status.IN_PROGRESS; } - } }); S3Utils.putObject(s3, putObjectRequest); + while (status != TemplateDownloader.Status.DOWNLOAD_FINISHED && + status != TemplateDownloader.Status.UNRECOVERABLE_ERROR && + status != TemplateDownloader.Status.ABORTED ){ + // wait for completion + } + // finished or aborted Date finish = new Date(); String downloaded = "(incomplete download)"; if (totalBytes >= remoteSize) { @@ -300,6 +318,9 @@ public class S3TemplateDownloader implements TemplateDownloader { } catch (IOException ioe) { status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; //probably a file write error? errorString = ioe.getMessage(); + } catch (AmazonClientException ex) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; // S3 api exception + errorString = ex.getMessage(); } finally { // close input stream request.releaseConnection(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java new file mode 100644 index 00000000000..a5c0af1ef20 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -0,0 +1,103 @@ +package org.apache.cloudstack.storage; + +import static com.cloud.utils.StringUtils.join; +import static java.util.Arrays.asList; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; +import java.util.concurrent.Executors; + +import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; +import org.springframework.stereotype.Component; + +import com.amazonaws.services.s3.model.S3ObjectSummary; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; +import com.cloud.agent.api.to.S3TO; +import com.cloud.agent.api.to.SwiftTO; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.resource.NfsSecondaryStorageResource; +import com.cloud.storage.template.DownloadManagerImpl; +import com.cloud.utils.S3Utils; +import com.cloud.utils.UriUtils; +import com.cloud.utils.exception.CloudRuntimeException; + +@Component +public class MockLocalNfsSecondaryStorageResource extends + NfsSecondaryStorageResource { + + public MockLocalNfsSecondaryStorageResource(){ + _dlMgr = new DownloadManagerImpl(); + ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); + } + + @Override + public Answer executeRequest(Command cmd) { + if (cmd instanceof DownloadSystemTemplateCommand){ + return execute((DownloadSystemTemplateCommand)cmd); + } else { + //return Answer.createUnsupportedCommandAnswer(cmd); + return super.executeRequest(cmd); + } + } + + private Answer execute(DownloadSystemTemplateCommand cmd){ + DataStoreTO dstore = cmd.getDataStore(); + if ( dstore instanceof S3TO ){ + //TODO: how to handle download progress for S3 + S3TO s3 = (S3TO)cmd.getDataStore(); + String url = cmd.getUrl(); + String user = null; + String password = null; + if (cmd.getAuth() != null) { + user = cmd.getAuth().getUserName(); + password = new String(cmd.getAuth().getPassword()); + } + // get input stream from the given url + InputStream in = UriUtils.getInputStreamFromUrl(url, user, password); + URI uri; + URL urlObj; + try { + uri = new URI(url); + urlObj = new URL(url); + } catch (URISyntaxException e) { + throw new CloudRuntimeException("URI is incorrect: " + url); + } catch (MalformedURLException e) { + throw new CloudRuntimeException("URL is incorrect: " + url); + } + + final String bucket = s3.getBucketName(); + // convention is no / in the end for install path based on S3Utils implementation. + String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); + // template key is + // TEMPLATE_ROOT_DIR/account_id/template_id/template_name + String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR); + S3Utils.putObject(s3, in, bucket, key); + List s3Obj = S3Utils.getDirectory(s3, bucket, path); + if (s3Obj == null || s3Obj.size() == 0) { + return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key); + } else { + return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj.get(0) + .getETag()); + } + } + else if ( dstore instanceof NfsTO ){ + return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates"); + } + else if ( dstore instanceof SwiftTO ){ + //TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle + // source is url, most likely we need to modify our existing swiftUpload python script. + return new Answer(cmd, false, "Swift is not currently support DownloadCommand"); + } + else{ + return new Answer(cmd, false, "Unsupported image data store: " + dstore); + } + } +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java index 4d4d037de30..9b9f03d2d53 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java @@ -18,6 +18,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; @@ -108,8 +109,11 @@ public class S3TemplateTest extends CloudStackTestNGBase { image = templateDao.persist(image); templateId = image.getId(); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(new LocalHostEndpoint()); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(new LocalHostEndpoint()); + // inject mockito + LocalHostEndpoint ep = new LocalHostEndpoint(); + ep.setResource(new MockLocalNfsSecondaryStorageResource()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); } @Test diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index 55f7edf1e0b..ad4829bc1b0 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -29,8 +29,16 @@ - - + + + + + + + + + + diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index ea93560934b..170772596a0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -92,5 +92,13 @@ public class LocalHostEndpoint implements EndPoint { executor.schedule(new CmdRunner2(cmd, listener.getCallback()), 10, TimeUnit.SECONDS); } } + public ServerResource getResource() { + return resource; + } + public void setResource(ServerResource resource) { + this.resource = resource; + } + + } From acafccfbc68d46362fd952107bd298be0d2cfc3e Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 3 May 2013 15:00:47 -0700 Subject: [PATCH 096/303] fix volume state change --- .../motion/AncientDataMotionStrategy.java | 16 ++++++------- .../cloudstack/storage/test/VolumeTest.java | 4 +++- .../storage/volume/VolumeServiceImpl.java | 23 +++++++++---------- 3 files changed, 22 insertions(+), 21 deletions(-) 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 index 66001ad408b..32f9a9aa101 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -248,12 +248,11 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected Answer cloneVolume(DataObject template, DataObject volume) { CopyCommand cmd = new CopyCommand(template.getTO(), volume.getTO(), 0); - StoragePool pool = (StoragePool)volume.getDataStore(); - try { - Answer answer = storageMgr.sendToPool(pool, null, cmd); + EndPoint ep = this.selector.select(volume.getDataStore()); + Answer answer = ep.sendMessage(cmd); return answer; - } catch (StorageUnavailableException e) { + } catch (Exception e) { s_logger.debug("Failed to send to storage pool", e); throw new CloudRuntimeException("Failed to send to storage pool", e); } @@ -302,16 +301,17 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { destData.getType() == DataObjectType.SNAPSHOT) { answer = copySnapshot(srcData, destData); } + + if (answer != null && !answer.getResult()) { + errMsg = answer.getDetails(); + } } catch (Exception e) { s_logger.debug("copy failed", e); errMsg = e.toString(); } CopyCommandResult result = new CopyCommandResult(null, answer); - if (!answer.getResult()) { - result.setResult(answer.getDetails()); - } + result.setResult(errMsg); callback.complete(result); - return null; } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index cceceda35ba..c4a1d01b1a3 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -240,9 +240,11 @@ public class VolumeTest extends CloudStackTestNGBase { List hosts = new ArrayList(); hosts.add(this.host); Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(new LocalHostEndpoint()); + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); } public DataStore createPrimaryDataStore() { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 07a5430aa6d..1f049cd8c09 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -401,12 +401,12 @@ public class VolumeServiceImpl implements VolumeService { } private class CreateVolumeFromBaseImageContext extends AsyncRpcConext { - private final VolumeObject vo; + private final DataObject vo; private final AsyncCallFuture future; private final DataStore primaryStore; private final DataObject templateOnStore; private final SnapshotInfo snapshot; - public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject vo, + public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, DataObject vo, DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture future, SnapshotInfo snapshot) { @@ -426,14 +426,13 @@ public class VolumeServiceImpl implements VolumeService { @DB protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture future) { - VolumeObject vo = (VolumeObject)volume; - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, vo, pd, templateOnPrimaryStore, future, null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)) - .setContext(context); - DataObject volumeOnPrimaryStorage = pd.create(volume); - volume.processEvent(Event.CreateOnlyRequested); + volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested); + + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)); + caller.setContext(context); motionSrv.copyAsync(context.templateOnStore, volumeOnPrimaryStorage, caller); return; @@ -441,9 +440,9 @@ public class VolumeServiceImpl implements VolumeService { @DB protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { - VolumeObject vo = context.vo; + DataObject vo = context.vo; CopyCommandResult result = callback.getResult(); - VolumeApiResult volResult = new VolumeApiResult(vo); + VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo); if (result.isSuccess()) { vo.processEvent(Event.OperationSuccessed, result.getAnswer()); @@ -516,7 +515,7 @@ public class VolumeServiceImpl implements VolumeService { protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); - VolumeInfo volume = context.vo; + VolumeInfo volume = (VolumeInfo)context.vo; SnapshotInfo snapshot = context.snapshot; VolumeApiResult apiResult = new VolumeApiResult(volume); Event event = null; From 23d6f12e9ad094984beae455fc74361fbbe0131f Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 3 May 2013 15:44:38 -0700 Subject: [PATCH 097/303] fix db select --- .../cloudstack/storage/endpoint/DefaultEndPointSelector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 8415ad2e6d1..5b223010d9b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -59,7 +59,7 @@ public class DefaultEndPointSelector implements EndPointSelector { HostDao hostDao; private String findOneHostInaScope = "select id from host where " + " status = 'Up' and hypervisor_type != 'VMware' and type in ('Routing', 'SecondaryStorageVM') "; - private String findOneHostOnPrimaryStorage = "select id from host where" + private String findOneHostOnPrimaryStorage = "select id from host where " + "status = 'Up' and type = 'Routing' "; protected boolean moveBetweenPrimaryImage(DataStore srcStore, From e0ab845e92ceb55aa9b3fddd65114c7f66677941 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 3 May 2013 17:29:12 -0700 Subject: [PATCH 098/303] Add gson adapter to serialize/deserialize DataTO and DataStoreTO. --- .../agent/transport/InterfaceTypeAdaptor.java | 66 +++++++++++++++++++ core/src/com/cloud/serializer/GsonHelper.java | 7 ++ .../template/S3TemplateDownloader.java | 3 +- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 core/src/com/cloud/agent/transport/InterfaceTypeAdaptor.java diff --git a/core/src/com/cloud/agent/transport/InterfaceTypeAdaptor.java b/core/src/com/cloud/agent/transport/InterfaceTypeAdaptor.java new file mode 100644 index 00000000000..1ad4afc1948 --- /dev/null +++ b/core/src/com/cloud/agent/transport/InterfaceTypeAdaptor.java @@ -0,0 +1,66 @@ +// 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.agent.transport; + +import java.lang.reflect.Type; +import java.util.Map; + +import com.cloud.utils.exception.CloudRuntimeException; +import com.google.gson.Gson; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; + +public class InterfaceTypeAdaptor implements JsonDeserializer, JsonSerializer { + + protected Gson _gson = null; + + + public InterfaceTypeAdaptor() { + } + + public void initGson(Gson gson) { + _gson = gson; + } + + @Override + public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject obj = new JsonObject(); + obj.add(src.getClass().getName(), _gson.toJsonTree(src)); + return obj; + } + + @Override + @SuppressWarnings("unchecked") + public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + JsonObject element = (JsonObject) json; + Map.Entry entry = element.entrySet().iterator().next(); + String name = entry.getKey(); + Class clazz; + try { + clazz = Class.forName(name); + } catch (ClassNotFoundException e) { + throw new CloudRuntimeException("can't find " + name); + } + return (T) _gson.fromJson(entry.getValue(), clazz); + } +} \ No newline at end of file diff --git a/core/src/com/cloud/serializer/GsonHelper.java b/core/src/com/cloud/serializer/GsonHelper.java index 8b2dcb0e928..47e99220167 100644 --- a/core/src/com/cloud/serializer/GsonHelper.java +++ b/core/src/com/cloud/serializer/GsonHelper.java @@ -20,12 +20,15 @@ package com.cloud.serializer; import java.util.List; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.transport.ArrayTypeAdaptor; +import com.cloud.agent.transport.InterfaceTypeAdaptor; import com.cloud.agent.transport.LoggingExclusionStrategy; import com.cloud.agent.transport.Request.NwGroupsCommandTypeAdaptor; import com.cloud.agent.transport.Request.PortConfigListTypeAdaptor; @@ -52,6 +55,10 @@ public class GsonHelper { static Gson setDefaultGsonConfig(GsonBuilder builder) { builder.setVersion(1.5); + InterfaceTypeAdaptor dsAdaptor = new InterfaceTypeAdaptor(); + builder.registerTypeAdapter(DataStoreTO.class, dsAdaptor); + InterfaceTypeAdaptor dtAdaptor = new InterfaceTypeAdaptor(); + builder.registerTypeAdapter(DataTO.class, dtAdaptor); ArrayTypeAdaptor cmdAdaptor = new ArrayTypeAdaptor(); builder.registerTypeAdapter(Command[].class, cmdAdaptor); ArrayTypeAdaptor ansAdaptor = new ArrayTypeAdaptor(); diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index eac9bbf6922..bc0b90435fa 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -308,8 +308,9 @@ public class S3TemplateDownloader implements TemplateDownloader { if (totalBytes >= remoteSize) { status = TemplateDownloader.Status.DOWNLOAD_FINISHED; downloaded = "(download complete remote=" + remoteSize + "bytes)"; + } else { + errorString = "Downloaded " + totalBytes + " bytes " + downloaded; } - errorString = "Downloaded " + totalBytes + " bytes " + downloaded; downloadTime += finish.getTime() - start.getTime(); return totalBytes; }catch (HttpException hte) { From bb7a72b7d6be3003b7b217569d6d0a9a35e19711 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 3 May 2013 17:42:39 -0700 Subject: [PATCH 099/303] Add unit test for DataTO/DataStoreTO serializer/deserializer adapter. --- core/src/com/cloud/serializer/GsonHelper.java | 2 ++ .../cloud/agent/transport/RequestTest.java | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/core/src/com/cloud/serializer/GsonHelper.java b/core/src/com/cloud/serializer/GsonHelper.java index 47e99220167..5656d910959 100644 --- a/core/src/com/cloud/serializer/GsonHelper.java +++ b/core/src/com/cloud/serializer/GsonHelper.java @@ -68,6 +68,8 @@ public class GsonHelper { builder.registerTypeAdapter(new TypeToken>() { }.getType(), new NwGroupsCommandTypeAdaptor()); Gson gson = builder.create(); + dsAdaptor.initGson(gson); + dtAdaptor.initGson(gson); cmdAdaptor.initGson(gson); ansAdaptor.initGson(gson); return gson; diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 141beb8650b..27bb4ff7426 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -30,6 +30,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.GetHostStatsCommand; import com.cloud.agent.api.SecStorageFirewallCfgCommand; +import com.cloud.agent.api.SecStorageSetupCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.to.NfsTO; @@ -129,6 +130,36 @@ public class RequestTest extends TestCase { compareRequest(cresp, sresp); } + + public void testSerDeserTO() { + s_logger.info("Testing serializing and deserializing interface TO works as expected"); + + NfsTO nfs = new NfsTO("nfs://192.168.56.10/opt/storage/secondary", DataStoreRole.Image); + SecStorageSetupCommand cmd = new SecStorageSetupCommand(nfs, "nfs://192.168.56.10/opt/storage/secondary", null); + Request sreq = new Request(2, 3, cmd, true); + sreq.setSequence(892403718); + + + byte[] bytes = sreq.getBytes(); + + assert Request.getSequence(bytes) == 892403718; + assert Request.getManagementServerId(bytes) == 3; + assert Request.getAgentId(bytes) == 2; + assert Request.getViaAgentId(bytes) == 2; + Request creq = null; + try { + creq = Request.parse(bytes); + } catch (ClassNotFoundException e) { + s_logger.error("Unable to parse bytes: ", e); + } catch (UnsupportedVersionException e) { + s_logger.error("Unable to parse bytes: ", e); + } + + assert creq != null : "Couldn't get the request back"; + + compareRequest(creq, sreq); + } + public void testDownload() { s_logger.info("Testing Download answer"); VMTemplateVO template = new VMTemplateVO(1, "templatename", ImageFormat.QCOW2, true, true, true, TemplateType.USER, "url", true, 32, 1, "chksum", "displayText", true, 30, true, From a221ecb48444b7ec53682a1db9baf5c73e14d35f Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sat, 4 May 2013 23:09:23 -0700 Subject: [PATCH 100/303] Workaround an issue of null url when ListTemplateCommand is received on SSVM side, also fix a bug in listTemplates with id passed. --- .../api/storage/ListTemplateCommand.java | 11 +++-- .../agent/api/storage/ListVolumeCommand.java | 9 +++- .../resource/NfsSecondaryStorageResource.java | 45 ++++++++++++++++--- .../storage/image/TemplateServiceImpl.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 4 +- .../com/cloud/api/query/QueryManagerImpl.java | 5 ++- 6 files changed, 62 insertions(+), 14 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java index 4a15887a9af..390f09b51b0 100644 --- a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java @@ -16,19 +16,18 @@ // under the License. package com.cloud.agent.api.storage; -import com.cloud.agent.api.LogLevel; -import com.cloud.agent.api.LogLevel.Log4jLevel; import com.cloud.agent.api.to.DataStoreTO; public class ListTemplateCommand extends StorageCommand { - @LogLevel(Log4jLevel.Off) private DataStoreTO store; + private String secUrl; public ListTemplateCommand() { } - public ListTemplateCommand(DataStoreTO store) { + public ListTemplateCommand(DataStoreTO store, String url) { this.store = store; + this.secUrl = url; } @Override @@ -41,4 +40,8 @@ public class ListTemplateCommand extends StorageCommand { return store; } + public String getSecUrl() { + return secUrl; + } + } diff --git a/api/src/com/cloud/agent/api/storage/ListVolumeCommand.java b/api/src/com/cloud/agent/api/storage/ListVolumeCommand.java index 63c5b621c6e..0de44defdb1 100755 --- a/api/src/com/cloud/agent/api/storage/ListVolumeCommand.java +++ b/api/src/com/cloud/agent/api/storage/ListVolumeCommand.java @@ -16,15 +16,19 @@ // under the License. package com.cloud.agent.api.storage; +import com.cloud.agent.api.to.DataStoreTO; + public class ListVolumeCommand extends StorageCommand { + private DataStoreTO store; private String secUrl; public ListVolumeCommand() { } - public ListVolumeCommand(String secUrl) { + public ListVolumeCommand(DataStoreTO store, String secUrl) { + this.store = store; this.secUrl = secUrl; } @@ -37,4 +41,7 @@ public class ListVolumeCommand extends StorageCommand { return secUrl; } + public DataStoreTO getDataStore() { + return store; + } } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 0345f6b0e90..9c09faa6723 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -327,6 +327,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(asList(VOLUME_ROOT_DIR, accountId, volId), S3Utils.SEPARATOR); } + @SuppressWarnings("unchecked") + protected Long determineS3VolumeIdFromKey(String key) { + return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR)); + } + @SuppressWarnings("unchecked") private String determineStorageTemplatePath(final String storagePath, String dataPath) { return join(asList(getRootDir(storagePath), dataPath), File.separator); @@ -1121,6 +1126,25 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } + Map s3ListVolume(S3TO s3) { + String bucket = s3.getBucketName(); + // List the objects in the source directory on S3 + final List objectSummaries = S3Utils.getDirectory(s3, bucket, this.VOLUME_ROOT_DIR); + if (objectSummaries == null) + return null; + Map tmpltInfos = new HashMap(); + for (S3ObjectSummary objectSummary : objectSummaries) { + String key = objectSummary.getKey(); + String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); + Long id = this.determineS3VolumeIdFromKey(key); + // TODO: how to get volume template name + TemplateProp tInfo = new TemplateProp(id.toString(), installPath, objectSummary.getSize(), objectSummary.getSize(), true, false); + tmpltInfos.put(id, tInfo); + } + return tmpltInfos; + + } + private Answer execute(ListTemplateCommand cmd) { if (!_inSystemVM) { return new Answer(cmd, true, null); @@ -1129,9 +1153,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { NfsTO nfs = (NfsTO) store; - String root = getRootDir(nfs.getUrl()); + String secUrl = cmd.getSecUrl(); + String root = getRootDir(secUrl); Map templateInfos = _dlMgr.gatherTemplateInfo(root); - return new ListTemplateAnswer(nfs.getUrl(), templateInfos); + return new ListTemplateAnswer(secUrl, templateInfos); } else if (store instanceof SwiftTO) { SwiftTO swift = (SwiftTO) store; Map templateInfos = swiftListTemplate(swift); @@ -1150,9 +1175,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, null); } - String root = getRootDir(cmd.getSecUrl()); - Map templateInfos = _dlMgr.gatherVolumeInfo(root); - return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); + DataStoreTO store = cmd.getDataStore(); + if (store instanceof NfsTO) { + NfsTO nfs = (NfsTO)store; + String root = getRootDir(cmd.getSecUrl()); + Map templateInfos = _dlMgr.gatherVolumeInfo(root); + return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); + } else if (store instanceof S3TO ){ + S3TO s3 = (S3TO)store; + Map templateInfos = s3ListVolume(s3); + return new ListVolumeAnswer(s3.getBucketName(), templateInfos); + } else { + return new Answer(cmd, false, "Unsupported image data store: " + store); + } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 60b3f5389d8..b7b42e5d4c7 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -417,7 +417,7 @@ public class TemplateServiceImpl implements TemplateService { private Map listTemplate(DataStore ssStore) { - ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO()); + ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO(), ssStore.getUri()); EndPoint ep = _epSelector.select(ssStore); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 1f049cd8c09..ec38a21bd2d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -428,7 +428,7 @@ public class VolumeServiceImpl implements VolumeService { protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture future) { DataObject volumeOnPrimaryStorage = pd.create(volume); volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested); - + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)); @@ -828,7 +828,7 @@ public class VolumeServiceImpl implements VolumeService { } private Map listVolume(DataStore store) { - ListVolumeCommand cmd = new ListVolumeCommand(store.getUri()); + ListVolumeCommand cmd = new ListVolumeCommand(store.getTO(), store.getUri()); EndPoint ep = _epSelector.select(store); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 234d4102996..a79a2b296ce 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2643,7 +2643,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } // other criteria - if (keyword != null) { + if (templateId != null){ + sc.addAnd("id", SearchCriteria.Op.EQ, templateId); + } + else if (keyword != null) { sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); } else if (name != null) { sc.addAnd("name", SearchCriteria.Op.EQ, name); From bc244ccc8bae28eaca93558eb25ce68829f54650 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sun, 5 May 2013 19:21:09 -0700 Subject: [PATCH 101/303] Populate template_zone_ref for those cross-zone templates while adding an image store. --- .../com/cloud/storage/StorageManagerImpl.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 798ee56a84d..9f5d2fe80cf 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -25,6 +25,7 @@ import java.sql.ResultSet; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -147,6 +148,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateS3Dao; import com.cloud.storage.dao.VMTemplateSwiftDao; +import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.listener.VolumeStateListener; @@ -222,6 +224,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected VMTemplatePoolDao _vmTemplatePoolDao = null; @Inject + protected VMTemplateZoneDao _vmTemplateZoneDao; + @Inject protected VMTemplateSwiftDao _vmTemplateSwiftDao = null; @Inject protected VMTemplateS3Dao _vmTemplateS3Dao; @@ -1925,9 +1929,41 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C this._imageSrv.addSystemVMTemplatesToSecondary(store); } + // associate builtin template with zones associated with this image store + this.associateCrosszoneTemplatesToZone(dcId); + return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); } + private void associateCrosszoneTemplatesToZone(Long zoneId){ + VMTemplateZoneVO tmpltZone; + + List allTemplates = _vmTemplateDao.listAll(); + List dcIds = new ArrayList(); + if (zoneId != null) { + dcIds.add(zoneId); + } else { + List dcs = _dcDao.listAll(); + if (dcs != null) { + for (DataCenterVO dc : dcs) { + dcIds.add(dc.getId()); + } + } + } + + for (VMTemplateVO vt : allTemplates) { + if (vt.isCrossZones()) { + for (Long dcId : dcIds) { + tmpltZone = _vmTemplateZoneDao.findByZoneTemplate(dcId, vt.getId()); + if (tmpltZone == null) { + VMTemplateZoneVO vmTemplateZone = new VMTemplateZoneVO(dcId, vt.getId(), new Date()); + _vmTemplateZoneDao.persist(vmTemplateZone); + } + } + } + } + } + @Override public boolean deleteImageStore(DeleteImageStoreCmd cmd) { long storeId = cmd.getId(); From 7ad263b67e4e0f0ed06c5cb1c99ac5a1bbd5d423 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 11:29:57 -0700 Subject: [PATCH 102/303] Revert previous workaround for ListTemplateCommand, which is correct after updating the systemvm.iso on devcloud. --- .../cloud/agent/api/storage/ListTemplateCommand.java | 12 ++++++------ .../resource/NfsSecondaryStorageResource.java | 2 +- core/test/com/cloud/agent/transport/RequestTest.java | 5 ++++- .../storage/image/TemplateServiceImpl.java | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java b/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java index 390f09b51b0..e5339f2982d 100644 --- a/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java +++ b/api/src/com/cloud/agent/api/storage/ListTemplateCommand.java @@ -20,14 +20,14 @@ import com.cloud.agent.api.to.DataStoreTO; public class ListTemplateCommand extends StorageCommand { private DataStoreTO store; - private String secUrl; + //private String secUrl; public ListTemplateCommand() { } - public ListTemplateCommand(DataStoreTO store, String url) { + public ListTemplateCommand(DataStoreTO store) { this.store = store; - this.secUrl = url; +// this.secUrl = url; } @Override @@ -40,8 +40,8 @@ public class ListTemplateCommand extends StorageCommand { return store; } - public String getSecUrl() { - return secUrl; - } + // public String getSecUrl() { + // return secUrl; + // } } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 9c09faa6723..d9f91a33e84 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -1153,7 +1153,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { NfsTO nfs = (NfsTO) store; - String secUrl = cmd.getSecUrl(); + String secUrl = nfs.getUrl(); String root = getRootDir(secUrl); Map templateInfos = _dlMgr.gatherTemplateInfo(root); return new ListTemplateAnswer(secUrl, templateInfos); diff --git a/core/test/com/cloud/agent/transport/RequestTest.java b/core/test/com/cloud/agent/transport/RequestTest.java index 27bb4ff7426..510be91ae6e 100644 --- a/core/test/com/cloud/agent/transport/RequestTest.java +++ b/core/test/com/cloud/agent/transport/RequestTest.java @@ -33,6 +33,7 @@ import com.cloud.agent.api.SecStorageFirewallCfgCommand; import com.cloud.agent.api.SecStorageSetupCommand; import com.cloud.agent.api.UpdateHostPasswordCommand; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.to.NfsTO; import com.cloud.exception.UnsupportedVersionException; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -135,7 +136,8 @@ public class RequestTest extends TestCase { s_logger.info("Testing serializing and deserializing interface TO works as expected"); NfsTO nfs = new NfsTO("nfs://192.168.56.10/opt/storage/secondary", DataStoreRole.Image); - SecStorageSetupCommand cmd = new SecStorageSetupCommand(nfs, "nfs://192.168.56.10/opt/storage/secondary", null); + // SecStorageSetupCommand cmd = new SecStorageSetupCommand(nfs, "nfs://192.168.56.10/opt/storage/secondary", null); + ListTemplateCommand cmd = new ListTemplateCommand(nfs); Request sreq = new Request(2, 3, cmd, true); sreq.setSequence(892403718); @@ -158,6 +160,7 @@ public class RequestTest extends TestCase { assert creq != null : "Couldn't get the request back"; compareRequest(creq, sreq); + assertEquals("nfs://192.168.56.10/opt/storage/secondary", ((NfsTO)((ListTemplateCommand)creq.getCommand()).getDataStore()).getUrl()); } public void testDownload() { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index b7b42e5d4c7..60b3f5389d8 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -417,7 +417,7 @@ public class TemplateServiceImpl implements TemplateService { private Map listTemplate(DataStore ssStore) { - ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO(), ssStore.getUri()); + ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO()); EndPoint ep = _epSelector.select(ssStore); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { From 2e28515624ca248d1435894f137d09efd6debcfd Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 11:30:34 -0700 Subject: [PATCH 103/303] Fix the way to retrieve details map from api input. --- .../admin/storage/AddImageStoreCmd.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index 190b36a9234..ef9921de44c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -16,6 +16,9 @@ // under the License. package org.apache.cloudstack.api.command.admin.storage; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.Map; import org.apache.cloudstack.api.APICommand; @@ -53,7 +56,7 @@ public class AddImageStoreCmd extends BaseCmd { private String providerName; - @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store") + @Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the image store. Example: details[0].key=accesskey&details[0].value=s389ddssaa&details[1].key=secretkey&details[1].value=8dshfsss") private Map details; @@ -71,7 +74,19 @@ public class AddImageStoreCmd extends BaseCmd { } public Map getDetails() { - return details; + Map detailsMap = null; + if (!details.isEmpty()) { + detailsMap = new HashMap(); + Collection props = details.values(); + Iterator iter = props.iterator(); + while (iter.hasNext()) { + HashMap detail = (HashMap) iter.next(); + String key = detail.get("key"); + String value = detail.get("value"); + detailsMap.put(key, value); + } + } + return detailsMap; } public String getProviderName() { From db65dfbb12cf9f821cdba2aa6308011c1f52e385 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 15:10:31 -0700 Subject: [PATCH 104/303] Work around an issue in using IPC callback for HypervisorTemplateAdapter. --- .../async/AsyncCallbackDispatcher.java | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java index 26f46da37ba..acbc5b60541 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/async/AsyncCallbackDispatcher.java @@ -22,6 +22,8 @@ package org.apache.cloudstack.framework.async; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import org.apache.log4j.Logger; + import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Enhancer; @@ -30,32 +32,40 @@ import net.sf.cglib.proxy.MethodProxy; @SuppressWarnings("rawtypes") public class AsyncCallbackDispatcher implements AsyncCompletionCallback { - private Method _callbackMethod; + private static final Logger s_logger = Logger.getLogger(AsyncCallbackDispatcher.class); + + private Method _callbackMethod; private T _targetObject; private Object _contextObject; private Object _resultObject; - private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver(); - + private AsyncCallbackDriver _driver = new InplaceAsyncCallbackDriver(); + private AsyncCallbackDispatcher(T target) { assert(target != null); _targetObject = target; } - + public AsyncCallbackDispatcher attachDriver(AsyncCallbackDriver driver) { assert(driver != null); _driver = driver; - + return this; } - + public Method getCallbackMethod() { return _callbackMethod; } - + @SuppressWarnings("unchecked") public T getTarget() { Enhancer en = new Enhancer(); - en.setSuperclass(_targetObject.getClass()); + + Class clz = _targetObject.getClass(); + String clzName = clz.getName(); + if(clzName.contains("EnhancerByCloudStack")) + clz = clz.getSuperclass(); + + en.setSuperclass(clz); en.setCallbacks(new Callback[]{new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, @@ -64,7 +74,7 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { _callbackMethod.setAccessible(true); return null; } - }, + }, new MethodInterceptor() { @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, @@ -81,23 +91,30 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { return 0; }} ); - return (T)en.create(); + + try { + return (T)en.create(); + } catch(Throwable e) { + s_logger.error("Unexpected exception", e); + } + + return null; } public AsyncCallbackDispatcher setCallback(Object useless) { return this; } - + public AsyncCallbackDispatcher setContext(Object context) { _contextObject = context; return this; } - + @SuppressWarnings("unchecked") public

P getContext() { return (P)_contextObject; } - + public void complete(Object resultObject) { _resultObject = resultObject; _driver.performCompletionCallback(this); @@ -112,15 +129,15 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { Object getTargetObject() { return _targetObject; } - + public static AsyncCallbackDispatcher create(P target) { return new AsyncCallbackDispatcher(target); } - + public static boolean dispatch(Object target, AsyncCallbackDispatcher callback) { assert(callback != null); assert(target != null); - + try { callback.getCallbackMethod().invoke(target, callback, callback.getContext()); } catch (IllegalArgumentException e) { @@ -130,7 +147,7 @@ public class AsyncCallbackDispatcher implements AsyncCompletionCallback { } catch (InvocationTargetException e) { throw new RuntimeException("InvocationTargetException when invoking RPC callback for command: " + callback.getCallbackMethod().getName(), e); } - + return true; } } From 4db84fb45e1a6dbd4ec1d30a68fcd1ba527f1d5a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 15:11:42 -0700 Subject: [PATCH 105/303] Remove the hard-coded package assumption in Command serialization. --- core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java b/core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java index 8eddc0328b7..ffb26b6dc84 100755 --- a/core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java +++ b/core/src/com/cloud/agent/transport/ArrayTypeAdaptor.java @@ -39,8 +39,6 @@ public class ArrayTypeAdaptor implements JsonDeserializer, JsonSerialize protected Gson _gson = null; - private static final String s_pkg = Command.class.getPackage().getName() + "."; - public ArrayTypeAdaptor() { } @@ -53,7 +51,7 @@ public class ArrayTypeAdaptor implements JsonDeserializer, JsonSerialize JsonArray array = new JsonArray(); for (T cmd : src) { JsonObject obj = new JsonObject(); - obj.add(cmd.getClass().getName().substring(s_pkg.length()), _gson.toJsonTree(cmd)); + obj.add(cmd.getClass().getName(), _gson.toJsonTree(cmd)); array.add(obj); } @@ -71,7 +69,7 @@ public class ArrayTypeAdaptor implements JsonDeserializer, JsonSerialize JsonObject element = (JsonObject)it.next(); Map.Entry entry = element.entrySet().iterator().next(); - String name = s_pkg + entry.getKey(); + String name = entry.getKey(); Class clazz; try { clazz = Class.forName(name); From 0d78209b736cc0c67990e9179d3d465b4208ca51 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 15:12:33 -0700 Subject: [PATCH 106/303] Address various UI requirements by introducing provider constants. --- .../command/admin/storage/AddImageStoreCmd.java | 2 +- .../storage/template/DownloadManagerImpl.java | 7 +------ .../api/storage/DataStoreProvider.java | 8 ++++++++ .../storage/image/TemplateServiceImpl.java | 17 ++++++++++++++--- .../provider/DataStoreProviderManagerImpl.java | 12 +++++------- .../CloudStackImageStoreProviderImpl.java | 3 ++- .../provider/S3ImageStoreProviderImpl.java | 3 ++- .../provider/SampleImageStoreProviderImpl.java | 3 ++- .../provider/SwiftImageStoreProviderImpl.java | 6 ++---- .../CloudStackPrimaryDataStoreProviderImpl.java | 3 ++- .../template/HypervisorTemplateAdapter.java | 2 +- 11 files changed, 40 insertions(+), 26 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index ef9921de44c..8349774cbaf 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -75,7 +75,7 @@ public class AddImageStoreCmd extends BaseCmd { public Map getDetails() { Map detailsMap = null; - if (!details.isEmpty()) { + if (details != null && !details.isEmpty()) { detailsMap = new HashMap(); Collection props = details.values(); Iterator iter = props.iterator(); diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index cd6165d1e3b..12914b0ef45 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -505,12 +505,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); - String tmpDir = ""; - if (resourceType == ResourceType.TEMPLATE) { - tmpDir = installPathPrefix + File.separator + accountId + File.separator + id; - } else { - tmpDir = installPathPrefix + File.separator + id; - } + String tmpDir = installPathPrefix; try { 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 c0c1f76a30f..cdcdef8a8b4 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 @@ -25,6 +25,14 @@ import java.util.Set; public interface DataStoreProvider { + // constants for provider names + public static final String NFS_IMAGE = "NFS"; + public static final String S3_IMAGE = "S3"; + public static final String SWIFT_IMAGE = "Swift"; + public static final String SAMPLE_IMAGE = "Sample"; + + public static final String DEFAULT_PRIMARY = "DefaultPrimary"; + public static enum DataStoreProviderType { PRIMARY, IMAGE, diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 60b3f5389d8..30c71832715 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -62,6 +62,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; @@ -381,9 +382,19 @@ public class TemplateServiceImpl implements TemplateService { List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - deleteTemplateAsync(_templateFactory.getTemplate(tInfo.getId(), store)); - String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId; - s_logger.info(description); + //TODO: we cannot directly call deleteTemplateSync here to reuse delete logic since in this case, our db does not have this template at all. + VMTemplateVO template = _templateDao.findById(tInfo.getId()); + DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(store); + Answer answer = ep.sendMessage(dtCommand); + if (answer == null || !answer.getResult()) { + s_logger.info("Failed to deleted template at store: " + store.getName()); + + } else { + String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId; + s_logger.info(description); + } + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index e34a35ef2c1..796afe2d4df 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -31,9 +31,7 @@ import org.apache.cloudstack.api.response.StorageProviderResponse; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider.DataStoreProviderType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; @@ -90,7 +88,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } return providers; } - + public List getCacheDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { @@ -147,18 +145,18 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto @Override public DataStoreProvider getDefaultPrimaryDataStoreProvider() { - return this.getDataStoreProvider("cloudstack primary data store provider"); + return this.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY); } @Override public DataStoreProvider getDefaultImageDataStoreProvider() { - return this.getDataStoreProvider("CloudStack ImageStore Provider"); + return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE); } - + @Override public DataStoreProvider getDefaultCacheDataStoreProvider() { - return this.getDataStoreProvider("cloudstack image store provider"); + return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE); } @Override diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index 953a078464b..c9952e2a66d 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -25,6 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.storage.datastore.driver.CloudStackImageStoreDriverImpl; @@ -41,7 +42,7 @@ import com.cloud.utils.component.ComponentContext; @Component public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { - private final String providerName = "CloudStack ImageStore Provider"; + private final String providerName = DataStoreProvider.NFS_IMAGE; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java index 174e2dbc482..7efb59a6956 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java @@ -28,6 +28,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.storage.datastore.driver.S3ImageStoreDriverImpl; @@ -44,7 +45,7 @@ import com.cloud.utils.component.ComponentContext; @Component public class S3ImageStoreProviderImpl implements ImageStoreProvider { - private final String providerName = "S3"; + private final String providerName = DataStoreProvider.S3_IMAGE; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index 4b96da7d023..1a0614b5e66 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -26,6 +26,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.storage.datastore.driver.SampleImageStoreDriverImpl; @@ -38,7 +39,7 @@ import com.cloud.storage.ScopeType; import com.cloud.utils.component.ComponentContext; public class SampleImageStoreProviderImpl implements ImageStoreProvider { - private final String name = "sample image data store provider"; + private final String name = DataStoreProvider.SAMPLE_IMAGE; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java index 2ba2e9d7f3c..bd6f9f0c9f8 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java @@ -18,16 +18,14 @@ */ package org.apache.cloudstack.storage.datastore.provider; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.UUID; - import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.storage.datastore.driver.SwiftImageStoreDriverImpl; @@ -44,7 +42,7 @@ import com.cloud.utils.component.ComponentContext; @Component public class SwiftImageStoreProviderImpl implements ImageStoreProvider { - private final String providerName = "Swift"; + private final String providerName = DataStoreProvider.SWIFT_IMAGE; protected ImageStoreLifeCycle lifeCycle; protected ImageStoreDriver driver; @Inject diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java index af1d0c42df3..dc9d98511ac 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; @@ -34,7 +35,7 @@ import com.cloud.utils.component.ComponentContext; public class CloudStackPrimaryDataStoreProviderImpl implements PrimaryDataStoreProvider { - private final String providerName = "cloudstack primary data store provider"; + private final String providerName = DataStoreProvider.DEFAULT_PRIMARY; protected PrimaryDataStoreDriver driver; protected HypervisorHostListener listener; protected DataStoreLifeCycle lifecyle; diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index ae1e1788070..7e560e380fa 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -175,7 +175,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te TemplateInfo tmpl = this.imageFactory.getTemplate(template.getId(), imageStore); CreateTemplateContext context = new CreateTemplateContext(null, tmpl); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(this.createTemplateAsyncCallBack(null, null)); + caller.setCallback(caller.getTarget().createTemplateAsyncCallBack(null, null)); caller.setContext(context); this.imageService .createTemplateAsync(tmpl, imageStore, caller); From eb4965ef6344975761f891f84d50a96142297381 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 6 May 2013 16:56:04 -0700 Subject: [PATCH 107/303] CLOUDSTACK-2351: object store - UI - Infrastructure menu - secondary storages - add secondary storage - NFS provider - replace addSecondaryStorage API with new API addImageStore. --- ui/scripts/system.js | 228 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 207 insertions(+), 21 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 8d08584dc60..4daed382eaa 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -10367,7 +10367,108 @@ createForm: { title: 'label.add.secondary.storage', - fields: { + fields: { + provider: { + label: "Storage Provider", + select: function(args){ + $.ajax({ + url: createURL('listStorageProviders'), + data: { + type: 'image' + }, + success: function(json){ + var objs = json.liststorageprovidersresponse.dataStoreProvider; + var items = []; + if(objs != null) { + for(var i = 0; i < objs.length; i++){ + if(objs[i].name == 'CloudStack ImageStore Provider') + items.unshift({id: objs[i].name, description: objs[i].name}); + else + items.push({id: objs[i].name, description: objs[i].name}); + } + } + args.response.success({ + data: items + }); + + args.$select.change(function() { + var $form = $(this).closest('form'); + if($(this).val() == "CloudStack ImageStore Provider") { + //CloudStack ImageStore Provider + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if ($(this).val() == "S3") { + //CloudStack ImageStore Provider + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); + $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); + $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); + $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); + $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); + $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if($(this).val() == "Swift") { + //CloudStack ImageStore Provider + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + //Swift + $form.find('.form-item[rel=url]').css('display', 'inline-block'); + $form.find('.form-item[rel=account]').css('display', 'inline-block'); + $form.find('.form-item[rel=username]').css('display', 'inline-block'); + $form.find('.form-item[rel=key]').css('display', 'inline-block'); + } + }); + + args.$select.change(); + } + }); + } + }, + + + //CloudStack ImageStore Provider (begin) zoneid: { label: 'Zone', docID: 'helpSecondaryStorageZone', @@ -10403,30 +10504,115 @@ label: 'label.path', docID: 'helpSecondaryStoragePath', validation: { required: true } - } + }, + //CloudStack ImageStore Provider (end) + + + //S3 (begin) + accesskey: { label: 'label.s3.access_key', validation: { required: true } }, + secretkey: { label: 'label.s3.secret_key', validation: { required: true} }, + bucket: { label: 'label.s3.bucket', validation: { required: true} }, + endpoint: { label: 'label.s3.endpoint' }, + usehttps: { + label: 'label.s3.use_https', + isEditable: true, + isBoolean: true, + isChecked: true, + converter:cloudStack.converters.toBooleanText + }, + connectiontimeout: { label: 'label.s3.connection_timeout' }, + maxerrorretry: { label: 'label.s3.max_error_retry' }, + sockettimeout: { label: 'label.s3.socket_timeout' }, + //S3 (end) + + + //Swift (begin) + url: { label: 'label.url', validation: { required: true } }, + account: { label: 'label.account' }, + username: { label: 'label.username' }, + key: { label: 'label.key' } + //Swift (end) } }, action: function(args) { - var zoneId = args.data.zoneid; - var nfs_server = args.data.nfsServer; - var path = args.data.path; - var url = nfsURL(nfs_server, path); - - $.ajax({ - url: createURL("addSecondaryStorage&zoneId=" + zoneId + "&url=" + todb(url)), - dataType: "json", - success: function(json) { - var item = json.addsecondarystorageresponse.secondarystorage; - args.response.success({ - data:item - }); - }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - args.response.error(errorMsg); - } - }); + if(args.data.provider == 'CloudStack ImageStore Provider') { + var zoneid = args.data.zoneid; + var nfs_server = args.data.nfsServer; + var path = args.data.path; + var url = nfsURL(nfs_server, path); + + var data = { + provider: args.data.provider, + zoneid: zoneid, + url: url + }; + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + args.response.error(errorMsg); + } + }); + } + else if(args.data.provider == 'S3') { + $.ajax({ + url: createURL('addS3'), + data: { + provider: args.data.provider, + accesskey: args.data.accesskey, + secretkey: args.data.secretkey, + bucket: args.data.bucket, + endpoint: args.data.endpoint, + usehttps: (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false'), + connectiontimeout: args.data.connectiontimeout, + maxerrorretry: args.data.maxerrorretry, + sockettimeout: args.data.sockettimeout + }, + success: function(json) { + havingS3 = true; + var item = json.adds3response.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + else if(args.data.provider == 'Swift') { + $.ajax({ + url: createURL('addSwift'), + data: { + provider: args.data.provider, + url: args.data.url, + account: args.data.account, + username: args.data.username, + key: args.data.key + }, + success: function(json) { + havingSwift = true; + var item = json.addswiftresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + + }, notification: { From a00e30cb16a23a2af754701614bd03670932ce42 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 6 May 2013 17:18:49 -0700 Subject: [PATCH 108/303] CLOUDSTACK-2351: (1) object store - listStorageTypes API has been changed to return 'NFS'. Here is related UI change. (2) Infrastructure menu - secondary storages- add secondary storage dialog - fix a bug that this dialog failed to pop up when there is zero zone. --- ui/scripts/system.js | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 4daed382eaa..d46cae8c3ba 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -10381,7 +10381,7 @@ var items = []; if(objs != null) { for(var i = 0; i < objs.length; i++){ - if(objs[i].name == 'CloudStack ImageStore Provider') + if(objs[i].name == 'NFS') items.unshift({id: objs[i].name, description: objs[i].name}); else items.push({id: objs[i].name, description: objs[i].name}); @@ -10393,8 +10393,8 @@ args.$select.change(function() { var $form = $(this).closest('form'); - if($(this).val() == "CloudStack ImageStore Provider") { - //CloudStack ImageStore Provider + if($(this).val() == "NFS") { + //NFS $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); $form.find('.form-item[rel=path]').css('display', 'inline-block'); @@ -10416,7 +10416,7 @@ $form.find('.form-item[rel=key]').hide(); } else if ($(this).val() == "S3") { - //CloudStack ImageStore Provider + //NFS $form.find('.form-item[rel=zoneid]').hide(); $form.find('.form-item[rel=nfsServer]').hide(); $form.find('.form-item[rel=path]').hide(); @@ -10438,7 +10438,7 @@ $form.find('.form-item[rel=key]').hide(); } else if($(this).val() == "Swift") { - //CloudStack ImageStore Provider + //NFS $form.find('.form-item[rel=zoneid]').hide(); $form.find('.form-item[rel=nfsServer]').hide(); $form.find('.form-item[rel=path]').hide(); @@ -10468,7 +10468,7 @@ }, - //CloudStack ImageStore Provider (begin) + //NFS (begin) zoneid: { label: 'Zone', docID: 'helpSecondaryStorageZone', @@ -10483,14 +10483,19 @@ success: function(json) { var zones = json.listzonesresponse.zone; - args.response.success({ - data: $.map(zones, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } } }); } @@ -10505,7 +10510,7 @@ docID: 'helpSecondaryStoragePath', validation: { required: true } }, - //CloudStack ImageStore Provider (end) + //NFS (end) //S3 (begin) @@ -10536,7 +10541,7 @@ }, action: function(args) { - if(args.data.provider == 'CloudStack ImageStore Provider') { + if(args.data.provider == 'NFS') { var zoneid = args.data.zoneid; var nfs_server = args.data.nfsServer; var path = args.data.path; From fdee28439593c6a494c4e8aa5b80be2e73d1df22 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 6 May 2013 17:57:52 -0700 Subject: [PATCH 109/303] CLOUDSTACK-2351: object store - Infrastructure menu - secondary storages - add secondary storage dialog - implement Swift provider. --- ui/scripts/system.js | 54 +++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index d46cae8c3ba..d791f10e7d5 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -282,9 +282,9 @@ secondaryStorageCount: function(data) { $.ajax({ - url: createURL('listHosts'), + url: createURL('listImageStores'), data: { - type: 'SecondaryStorage', + type: 'image', page: 1, pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }, @@ -10322,16 +10322,9 @@ id: 'secondarystorages', section: 'seconary-storage', fields: { - name: { label: 'label.name' }, - created: { label: 'label.created', converter: cloudStack.converters.toLocalDate }, - resourcestate: { - label: 'label.state', - indicator: { - 'Enabled': 'on', - 'Disabled': 'off', - 'Destroyed': 'off' - } - } + providername: { label: 'Provider' }, + scope: { label: 'Scope' }, + url: { label: 'URL' } }, dataProvider: function(args) { @@ -10345,10 +10338,9 @@ break; } } - } - array1.push("&zoneid=" + args.context.zones[0].id); + } $.ajax({ - url: createURL("listHosts&type=SecondaryStorage&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + url: createURL("listImageStores&type=image&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: "json", async: true, success: function(json) { @@ -10369,7 +10361,7 @@ title: 'label.add.secondary.storage', fields: { provider: { - label: "Storage Provider", + label: 'Provider', select: function(args){ $.ajax({ url: createURL('listStorageProviders'), @@ -10473,13 +10465,12 @@ label: 'Zone', docID: 'helpSecondaryStorageZone', validation: { required: true }, - select: function(args) { - var data = args.context.zones ? - { id: args.context.zones[0].id } : { listAll: true }; - + select: function(args) { $.ajax({ url: createURL('listZones'), - data: data, + data: { + listAll: true + }, success: function(json) { var zones = json.listzonesresponse.zone; @@ -10570,7 +10561,7 @@ } else if(args.data.provider == 'S3') { $.ajax({ - url: createURL('addS3'), + url: createURL('addImageStore'), data: { provider: args.data.provider, accesskey: args.data.accesskey, @@ -10584,7 +10575,7 @@ }, success: function(json) { havingS3 = true; - var item = json.adds3response.secondarystorage; + var item = json.addimagestoreresponse.secondarystorage; args.response.success({ data:item }); @@ -10596,17 +10587,20 @@ } else if(args.data.provider == 'Swift') { $.ajax({ - url: createURL('addSwift'), + url: createURL('addImageStore'), data: { provider: args.data.provider, url: args.data.url, - account: args.data.account, - username: args.data.username, - key: args.data.key + 'details[0].key': 'account', + 'details[0].value': args.data.account, + 'details[1].key': 'username', + 'details[1].value': args.data.username, + 'details[2].key': 'key', + 'details[2].value': args.data.key }, success: function(json) { havingSwift = true; - var item = json.addswiftresponse.secondarystorage; + var item = json.addimagestoreresponse.secondarystorage; args.response.success({ data:item }); @@ -10615,9 +10609,7 @@ args.response.error(parseXMLHttpResponse(json)); } }); - } - - + } }, notification: { From f5d5526d41d4889aa252714e2cc6006598c63993 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 18:02:52 -0700 Subject: [PATCH 110/303] Fix unit test to test NFS template download flow. --- .../resource/NfsSecondaryStorageResource.java | 2 +- .../storage/template/DownloadManagerImpl.java | 15 +++++- .../MockLocalNfsSecondaryStorageResource.java | 12 +++++ .../cloudstack/storage/test/TemplateTest.java | 48 +++++++++++-------- .../integration-test/test/resource/testng.xml | 3 +- .../ResourceLimitManagerImpl.java | 1 + .../storage/download/DownloadListener.java | 2 +- .../template/HypervisorTemplateAdapter.java | 5 +- 8 files changed, 63 insertions(+), 25 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index d9f91a33e84..48854dfbcb5 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -140,7 +140,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String _guid; String _role; Map _params; - StorageLayer _storage; + protected StorageLayer _storage; boolean _inSystemVM = false; boolean _sslCopy = false; diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 12914b0ef45..53810e9083c 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -62,6 +62,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.exception.InternalErrorException; import com.cloud.storage.Storage.ImageFormat; @@ -245,6 +246,10 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager this.threadPool = threadPool; } + public void setStorageLayer(StorageLayer storage){ + this._storage = storage; + } + /** * Get notified of change of job status. Executed in context of downloader * thread @@ -656,8 +661,16 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager return new DownloadAnswer("Invalid Name", VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); } - String installPathPrefix = cmd.getInstallPath(); DataStoreTO dstore = cmd.getDataStore(); + String installPathPrefix = cmd.getInstallPath(); + // for NFS, we need to get mounted path + if (dstore instanceof NfsTO) { + if (ResourceType.TEMPLATE == resourceType) { + installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; + } else { + installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; + } + } String user = null; String password = null; if (cmd.getAuth() != null) { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index a5c0af1ef20..60dc16127fa 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -18,10 +18,12 @@ import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.storage.ssCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.resource.NfsSecondaryStorageResource; import com.cloud.storage.template.DownloadManagerImpl; @@ -35,7 +37,17 @@ public class MockLocalNfsSecondaryStorageResource extends public MockLocalNfsSecondaryStorageResource(){ _dlMgr = new DownloadManagerImpl(); + + _storage = new JavaStorageLayer(); ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); + ((DownloadManagerImpl)_dlMgr).setStorageLayer(_storage); + + } + + @Override + public String getRootDir(ssCommand cmd) { + return "/mnt"; + } @Override diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index ff540d95748..541f668e7d4 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -1,5 +1,7 @@ package org.apache.cloudstack.storage.test; +import static org.testng.Assert.assertTrue; + import java.util.UUID; import java.util.concurrent.ExecutionException; @@ -8,6 +10,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; @@ -15,6 +18,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.mockito.Mockito; @@ -34,7 +38,7 @@ import com.cloud.storage.download.DownloadMonitorImpl; import com.cloud.utils.component.ComponentContext; @ContextConfiguration(locations={"classpath:/storageContext.xml"}) - + public class TemplateTest extends CloudStackTestNGBase { @Inject DataCenterDao dcDao; @@ -55,7 +59,7 @@ public class TemplateTest extends CloudStackTestNGBase { DownloadMonitorImpl downloadMonitor; long dcId; long templateId; - + @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -64,17 +68,17 @@ public class TemplateTest extends CloudStackTestNGBase { null, null, NetworkType.Basic, null, null, true, true, null, null); dc = dcDao.persist(dc); dcId = dc.getId(); - + imageStore = new ImageStoreVO(); imageStore.setName("test"); imageStore.setDataCenterId(dcId); - imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setProviderName(DataStoreProvider.NFS_IMAGE); imageStore.setRole(DataStoreRole.Image); imageStore.setUrl(this.getSecondaryStorage()); imageStore.setUuid(UUID.randomUUID().toString()); imageStore.setProtocol("nfs"); imageStore = imageStoreDao.persist(imageStore); - + VMTemplateVO image = new VMTemplateVO(); image.setTemplateType(TemplateType.USER); image.setUrl(this.getTemplateUrl()); @@ -93,30 +97,36 @@ public class TemplateTest extends CloudStackTestNGBase { image.setCrossZones(true); image.setExtractable(true); - + //image.setImageDataStoreId(storeId); image = templateDao.persist(image); templateId = image.getId(); - - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(new LocalHostEndpoint()); - //Mockito.when(downloadMonitor.isTemplateUpdateable(Mockito.anyLong(), Mockito.anyLong())).thenReturn(true); + + // inject mockito + LocalHostEndpoint ep = new LocalHostEndpoint(); + ep.setResource(new MockLocalNfsSecondaryStorageResource()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); } - + @Test public void registerTemplate() { TemplateInfo template = templateFactory.getTemplate(templateId); DataStore store = dataStoreMgr.getImageStore(dcId); AsyncCallFuture future = new AsyncCallFuture(); templateSvr.createTemplateAsync(template, store, future); - try { - future.get(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + try { + TemplateApiResult result = future.get(); + assertTrue(result.isSuccess(), "failed to register template: " + result.getResult()); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } } } diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index ad4829bc1b0..dbadae1dde1 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -27,7 +27,8 @@ - + + diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index 49c3af1853b..818c5ab0291 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -227,6 +227,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim s_logger.trace("Not incrementing resource count for system accounts, returning"); return; } + long numToIncrement = (delta.length == 0) ? 1 : delta[0].longValue(); if (!updateResourceCountForAccount(accountId, type, true, numToIncrement)) { diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 001b45dc1c4..84c51b1ffdb 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -99,7 +99,7 @@ public class DownloadListener implements Listener { public static final Logger s_logger = Logger.getLogger(DownloadListener.class.getName()); public static final int SMALL_DELAY = 100; - public static final long STATUS_POLL_INTERVAL = 10000L; + public static final long STATUS_POLL_INTERVAL = 300000L; //10000L; public static final String DOWNLOADED=Status.DOWNLOADED.toString(); public static final String NOT_DOWNLOADED=Status.NOT_DOWNLOADED.toString(); diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 7e560e380fa..af77c925688 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -198,8 +198,9 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te TemplateInfo template = context.template; VMTemplateVO tmplt = this._tmpltDao.findById(template.getId()); long accountId = tmplt.getAccountId(); - _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, - template.getSize()); + if (template.getSize() != null) { + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize()); + } return null; } From 2d544e7127a195c07fd10b5b9482df33c15fa77d Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 6 May 2013 13:52:55 -0700 Subject: [PATCH 111/303] volume related operation works --- .../CopyTemplateToPrimaryStorageAnswer.java | 1 + .../api/storage/CopyCommandResult.java | 2 + .../api/storage/CreateCmdResult.java | 3 + .../api/storage/DataStoreDriver.java | 1 + .../api/storage/PrimaryDataStoreDriver.java | 1 + .../subsystem/api/storage/SnapshotResult.java | 2 + .../api/storage/TemplateService.java | 1 + .../subsystem/api/storage/VolumeService.java | 1 + .../command/AttachPrimaryDataStoreCmd.java | 1 + .../command}/CommandResult.java | 2 +- .../storage/command/CopyCmdAnswer.java | 1 + .../command/CreatePrimaryDataStoreCmd.java | 1 + .../storage/command/DeleteCommand.java | 12 +-- .../cloudstack/storage/to/VolumeObjectTO.java | 11 ++- .../manager/StorageCacheManagerImpl.java | 2 +- .../storage/image/TemplateServiceImpl.java | 6 +- .../storage/test/CloudStackTestNGBase.java | 14 ++- .../cloudstack/storage/test/SnapshotTest.java | 23 +++++ .../cloudstack/storage/test/TemplateTest.java | 5 + .../cloudstack/storage/test/VolumeTest.java | 92 ++++++++++++++++++- .../storage/test/volumeServiceTest.java | 2 +- .../storage/snapshot/SnapshotServiceImpl.java | 2 +- .../storage/datastore/DataObjectManager.java | 2 +- .../datastore/DataObjectManagerImpl.java | 2 +- .../image/motion/ImageMotionService.java | 2 +- .../storage/volume/VolumeObject.java | 8 ++ .../storage/volume/VolumeServiceImpl.java | 4 +- .../xen/resource/CitrixResourceBase.java | 3 +- .../resource/XenServerStorageResource.java | 29 ++++-- .../CloudStackImageStoreDriverImpl.java | 2 +- .../driver/S3ImageStoreDriverImpl.java | 2 +- .../driver/SampleImageStoreDriverImpl.java | 2 +- .../driver/SwiftImageStoreDriverImpl.java | 2 +- .../CloudStackPrimaryDataStoreDriverImpl.java | 27 ++---- .../SamplePrimaryDataStoreDriverImpl.java | 2 +- .../SolidfirePrimaryDataStoreDriver.java | 2 +- .../com/cloud/storage/TemplateProfile.java | 1 + .../template/HypervisorTemplateAdapter.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 2 +- 39 files changed, 219 insertions(+), 61 deletions(-) rename {engine/api/src/org/apache/cloudstack/storage/command => api/src/com/cloud/agent/api/storage}/CopyTemplateToPrimaryStorageAnswer.java (95%) rename engine/api/src/org/apache/cloudstack/{engine/subsystem/api/storage => storage/command}/CommandResult.java (95%) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java b/api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java similarity index 95% rename from engine/api/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java rename to api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java index b248758bc12..ecc8e576681 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyTemplateToPrimaryStorageAnswer.java +++ b/api/src/com/cloud/agent/api/storage/CopyTemplateToPrimaryStorageAnswer.java @@ -1,3 +1,4 @@ +package com.cloud.agent.api.storage; // 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 diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java index 571a77c3786..e9d7b110341 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import org.apache.cloudstack.storage.command.CommandResult; + import com.cloud.agent.api.Answer; public class CopyCommandResult extends CommandResult { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java index 4b78e54bb90..2ecd97d071d 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import org.apache.cloudstack.storage.command.CommandResult; + import com.cloud.agent.api.Answer; public class CreateCmdResult extends CommandResult { @@ -26,6 +28,7 @@ public class CreateCmdResult extends CommandResult { public CreateCmdResult(String path, Answer answer) { super(); this.path = path; + this.answer = answer; } public String getPath() { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java index e4986d675e0..cd2dc86cddc 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java @@ -21,6 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.Set; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; import com.cloud.agent.api.to.DataStoreTO; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java index 78a1014d3c7..4f0f99da8ec 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; public interface PrimaryDataStoreDriver extends DataStoreDriver { public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java index 29d094f90a4..21c0ea04bdf 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java @@ -1,6 +1,8 @@ package org.apache.cloudstack.engine.subsystem.api.storage; +import org.apache.cloudstack.storage.command.CommandResult; + import com.cloud.agent.api.Answer; public class SnapshotResult extends CommandResult { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index b0f9f37d85b..5e0c9f278a1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java index 8bca4790e23..0f6caa3cd9a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.CommandResult; import com.cloud.exception.ConcurrentOperationException; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java index 8aaca94aee0..15573a08a32 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.command; + import com.cloud.agent.api.Command; public class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CommandResult.java b/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java similarity index 95% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CommandResult.java rename to engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java index 6b6139b937d..c1a97ada991 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CommandResult.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.engine.subsystem.api.storage; +package org.apache.cloudstack.storage.command; public class CommandResult { private boolean success; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java index 4105d624107..3612cf98e5c 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.storage.command; + import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Answer; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java index 0e50950843e..59ed0a8c2ea 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java @@ -16,6 +16,7 @@ // under the License. package org.apache.cloudstack.storage.command; + import com.cloud.agent.api.Command; public class CreatePrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 3f62100b832..3335848bd86 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -18,14 +18,14 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Command; public class DeleteCommand extends Command implements StorageSubSystemCommand { - private String uri; - public DeleteCommand(String uri) { - this.uri = uri; + private DataTO data; + public DeleteCommand(DataTO data) { + this.data = data; } protected DeleteCommand() { @@ -37,8 +37,8 @@ public class DeleteCommand extends Command implements StorageSubSystemCommand { return false; } - public String getUri() { - return this.uri; + public DataTO getData() { + return this.data; } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 5e6ca2b79cb..3f7a8f1d335 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -33,6 +33,7 @@ public class VolumeObjectTO implements DataTO { private long size; private String path; private Long volumeId; + private String vmName; private long accountId; public VolumeObjectTO() { @@ -48,7 +49,7 @@ public class VolumeObjectTO implements DataTO { } else { this.dataStore = null; } - //this.name = volume.getName(); + this.vmName = volume.getAttachedVmName(); this.size = volume.getSize(); this.setVolumeId(volume.getId()); } @@ -121,5 +122,13 @@ public class VolumeObjectTO implements DataTO { this.accountId = accountId; } + public String getVmName() { + return vmName; + } + + public void setVmName(String vmName) { + this.vmName = vmName; + } + } 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 index 3a445d4d70e..1452e17a532 100644 --- 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 @@ -25,7 +25,6 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -38,6 +37,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.log4j.Logger; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 30c71832715..8e3f892cf51 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -29,7 +29,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; @@ -51,6 +50,7 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -377,7 +377,7 @@ public class TemplateServiceImpl implements TemplateService { } } - for (String uniqueName : templateInfos.keySet()) { + /* for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. @@ -396,7 +396,7 @@ public class TemplateServiceImpl implements TemplateService { } } - } + }*/ } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 4ea3d3ff85f..4d600785526 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -43,6 +43,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String s3SecretKey; private String s3EndPoint; private String s3TemplateBucket; + private String primaryStorageUuid; private boolean s3UseHttps; protected void injectMockito() { @@ -70,11 +71,11 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path"}) + "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path", "primary-storage-uuid-want-to-add"}) protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid, String primaryStorage, String secondaryStorage, String s3_accessKey, String s3_secretKey, String s3_endpoint, String s3_template_bucket, - String s3_usehttps, String imageInstallPath) { + String s3_usehttps, String imageInstallPath, String primaryStorageUuid) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -82,6 +83,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.templateUrl = templateUrl; this.localStorageUuid = localStorageUuid; this.primaryStorageUrl = primaryStorage; + this.primaryStorageUuid = primaryStorageUuid; this.imageInstallPath = imageInstallPath; this.setSecondaryStorage(secondaryStorage); // set S3 parameters @@ -157,4 +159,12 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.imageInstallPath = imageInstallPath; } + public String getPrimaryStorageUuid() { + return primaryStorageUuid; + } + + public void setPrimaryStorageUuid(String primaryStorageUuid) { + this.primaryStorageUuid = primaryStorageUuid; + } + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java new file mode 100644 index 00000000000..afd63f5bfdd --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.test; + +public class SnapshotTest { + +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index ff540d95748..164cced93b3 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -26,11 +26,14 @@ import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; +import com.cloud.storage.TemplateProfile; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.download.DownloadMonitorImpl; +import com.cloud.template.HypervisorTemplateAdapter; +import com.cloud.template.TemplateAdapter; import com.cloud.utils.component.ComponentContext; @ContextConfiguration(locations={"classpath:/storageContext.xml"}) @@ -53,6 +56,8 @@ public class TemplateTest extends CloudStackTestNGBase { EndPointSelector epSelector; @Inject DownloadMonitorImpl downloadMonitor; + + long dcId; long templateId; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index c4a1d01b1a3..01715451f33 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.concurrent.ExecutionException; import javax.inject.Inject; @@ -37,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManag import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; @@ -44,6 +46,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -58,6 +61,7 @@ import org.apache.cloudstack.storage.volume.db.VolumeDao2; import org.apache.cloudstack.storage.volume.db.VolumeVO; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; import org.testng.annotations.Test; import com.cloud.agent.AgentManager; @@ -68,6 +72,7 @@ import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; +import com.cloud.exception.ConcurrentOperationException; import com.cloud.host.Host; import com.cloud.host.Host.Type; import com.cloud.host.HostVO; @@ -78,9 +83,12 @@ import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; +import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; @@ -255,7 +263,7 @@ public class VolumeTest extends CloudStackTestNGBase { return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); } - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); + /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); Map params = new HashMap(); URI uri = new URI(this.getPrimaryStorageUrl()); params.put("url", this.getPrimaryStorageUrl()); @@ -274,7 +282,24 @@ public class VolumeTest extends CloudStackTestNGBase { DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); DataStore store = lifeCycle.initialize(params); ClusterScope scope = new ClusterScope(clusterId, podId, dcId); - lifeCycle.attachCluster(store, scope); + lifeCycle.attachCluster(store, scope);*/ + + StoragePoolVO pool = new StoragePoolVO(); + pool.setClusterId(clusterId); + pool.setDataCenterId(dcId); + URI uri = new URI(this.getPrimaryStorageUrl()); + pool.setHostAddress(uri.getHost()); + pool.setPath(uri.getPath()); + pool.setPort(0); + pool.setName(this.primaryName); + pool.setUuid(this.getPrimaryStorageUuid()); + pool.setStatus(StoragePoolStatus.Up); + pool.setPoolType(StoragePoolType.NetworkFilesystem); + pool.setPodId(podId); + pool.setScope(ScopeType.CLUSTER); + pool.setStorageProviderName("cloudstack primary data store provider"); + pool = this.primaryStoreDao.persist(pool); + DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); return store; } catch (Exception e) { return null; @@ -283,18 +308,75 @@ public class VolumeTest extends CloudStackTestNGBase { private VolumeVO createVolume(Long templateId, long dataStoreId) { VolumeVO volume = new VolumeVO(1000, new RootDisk().toString(), UUID.randomUUID().toString(), templateId); - //volume.setPoolId(dataStoreId); + volume.setPoolId(dataStoreId); volume = volumeDao.persist(volume); return volume; } - @Test + //@Test public void testCopyBaseImage() { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId())); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId())); + try { + VolumeApiResult result = future.get(); + + AssertJUnit.assertTrue(result.isSuccess()); + + VolumeInfo newVol = result.getVolume(); + this.volumeService.destroyVolume(newVol.getId()); + VolumeInfo vol = this.volFactory.getVolume(volume.getId()); + this.volumeService.expungeVolumeAsync(vol); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Test + public void testCreateDataDisk() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + this.volumeService.createVolumeAsync(volInfo, primaryStore); + } + + @Test + public void testDeleteDisk() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); + try { + VolumeApiResult result = future.get(); + VolumeInfo vol = result.getVolume(); + + this.volumeService.destroyVolume(volInfo.getId()); + volInfo = this.volFactory.getVolume(vol.getId()); + this.volumeService.expungeVolumeAsync(volInfo); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 2152b2e64eb..3b915dc8dac 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -31,7 +31,6 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; @@ -50,6 +49,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeAp import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.RemoteHostEndPoint; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 615ed2002f3..79237c4ffc6 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -22,7 +22,6 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; @@ -42,6 +41,7 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java index 20bf0545dc9..177dc3e89e7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java @@ -18,11 +18,11 @@ */ package org.apache.cloudstack.storage.datastore; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; public interface DataObjectManager { public void createAsync(DataObject data, DataStore store, AsyncCompletionCallback callback, boolean noCopy); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java index 566da62389e..c4eb2e436d4 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java @@ -20,7 +20,6 @@ package org.apache.cloudstack.storage.datastore; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; @@ -32,6 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java index 908d6d52c20..b37641300ed 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java @@ -18,9 +18,9 @@ */ package org.apache.cloudstack.storage.image.motion; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index ffac68e3af6..1aee5d304a0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; @@ -380,6 +381,13 @@ public class VolumeObject implements VolumeInfo { vol.setPath(newVol.getPath()); vol.setSize(newVol.getSize()); volumeDao.update(vol.getId(), vol); + } else if (answer instanceof CreateObjectAnswer) { + CreateObjectAnswer createAnswer =(CreateObjectAnswer)answer; + VolumeObjectTO newVol = (VolumeObjectTO)createAnswer.getData(); + VolumeVO vol = this.volumeDao.findById(this.getId()); + vol.setPath(newVol.getPath()); + vol.setSize(newVol.getSize()); + volumeDao.update(vol.getId(), vol); } } else if (this.dataStore.getRole() == DataStoreRole.Image) { if (answer instanceof DownloadAnswer) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index ec38a21bd2d..74e01be4892 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -26,7 +26,6 @@ import java.util.Map; import javax.inject.Inject; import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; @@ -44,6 +43,7 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; @@ -165,7 +165,7 @@ public class VolumeServiceImpl implements VolumeService { DataObject vo = context.getVolume(); String errMsg = null; if (result.isSuccess()) { - vo.processEvent(Event.OperationSuccessed); + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); } else { vo.processEvent(Event.OperationFailed); errMsg = result.getResult(); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index cdc8da9e8f9..c88a7462f8f 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -54,9 +54,10 @@ import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; import com.cloud.agent.api.*; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import com.cloud.agent.api.to.*; import com.cloud.network.rules.FirewallRule; + +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.w3c.dom.Document; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 77e5ca66b5a..42099499ce5 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -42,11 +42,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; -import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; import org.apache.cloudstack.storage.to.ImageStoreTO; @@ -113,8 +114,8 @@ public class XenServerStorageResource { return execute((CreatePrimaryDataStoreCmd) command); } else if (command instanceof CreateObjectCommand) { return execute((CreateObjectCommand) command); - } else if (command instanceof DeleteVolumeCommand) { - return execute((DeleteVolumeCommand)command); + } else if (command instanceof DeleteCommand) { + return execute((DeleteCommand)command); } return new Answer((Command)command, false, "not implemented yet"); } @@ -222,15 +223,14 @@ public class XenServerStorageResource { return new CreateObjectAnswer(e.toString()); } } - - protected Answer execute(DeleteVolumeCommand cmd) { - VolumeObjectTO volume = null; + + protected Answer deleteVolume(VolumeObjectTO volume) { Connection conn = hypervisorResource.getConnection(); String errorMsg = null; try { - VDI vdi = VDI.getByUuid(conn, volume.getUuid()); + VDI vdi = VDI.getByUuid(conn, volume.getPath()); deleteVDI(conn, vdi); - return new Answer(cmd); + return new Answer(null); } catch (BadServerResponse e) { s_logger.debug("Failed to delete volume", e); errorMsg = e.toString(); @@ -241,8 +241,19 @@ public class XenServerStorageResource { s_logger.debug("Failed to delete volume", e); errorMsg = e.toString(); } + return new Answer(null, false, errorMsg); + } - return new Answer(cmd, false, errorMsg); + protected Answer execute(DeleteCommand cmd) { + DataTO data = cmd.getData(); + Answer answer = null; + if (data.getObjectType() == DataObjectType.VOLUME) { + answer = deleteVolume((VolumeObjectTO)data); + } else { + answer = new Answer(cmd, false, "unsupported type"); + } + + return answer; } /* protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 382ae44d7c4..c30d8a6bbc4 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -24,7 +24,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -38,6 +37,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index c92ea26152d..b64f934d625 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -26,7 +26,6 @@ import java.util.Set; import javax.inject.Inject; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -40,6 +39,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index e477b570e79..72864c3513a 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -22,7 +22,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -32,6 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.image.ImageStoreDriver; diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 10310773bc5..8446eeb2b5f 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -26,7 +26,6 @@ import java.util.Set; import javax.inject.Inject; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -39,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 93d37ded506..6acded982a9 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -22,7 +22,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -30,11 +29,14 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; 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.command.CommandResult; import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.volume.VolumeObject; @@ -80,6 +82,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Inject SnapshotDao snapshotDao; @Inject PrimaryDataStoreDao primaryStoreDao; @Inject SnapshotManager snapshotMgr; + @Inject EndPointSelector epSelecotor; @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -117,7 +120,8 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO()); - Answer answer = storageMgr.sendToPool((StoragePool)volume.getDataStore(), null, cmd); + EndPoint ep = epSelecotor.select(volume); + Answer answer = ep.sendMessage(cmd); return answer; } @@ -149,28 +153,17 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Override public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { - - String vmName = null; - VolumeVO vol = this.volumeDao.findById(data.getId()); - - - StoragePool pool = (StoragePool)data.getDataStore(); - - DestroyCommand cmd = new DestroyCommand(pool, vol, vmName); + DeleteCommand cmd = new DeleteCommand(data.getTO()); CommandResult result = new CommandResult(); try { - Answer answer = this.storageMgr.sendToPool(pool, cmd); + EndPoint ep = epSelecotor.select(data); + Answer answer = ep.sendMessage(cmd); if (answer != null && !answer.getResult()) { result.setResult(answer.getDetails()); - s_logger.info("Will retry delete of " + vol + " from " + pool.getId()); } - } catch (StorageUnavailableException e) { - s_logger.error("Storage is unavailable currently. Will retry delete of " - + vol + " from " + pool.getId(), e); - result.setResult(e.toString()); } catch (Exception ex) { - s_logger.debug("Unable to destoy volume" + vol + " from " + pool.getId(), ex); + s_logger.debug("Unable to destoy volume" + data.getId(), ex); result.setResult(ex.toString()); } callback.complete(result); diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index a9226c7da39..c8a2a0c2e55 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -21,7 +21,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -34,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.DeleteCommand; diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 4ec0373316e..9b2334bb60e 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -18,7 +18,6 @@ package org.apache.cloudstack.storage.datastore.driver; import java.util.Set; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -28,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; import com.cloud.agent.api.to.DataStoreTO; diff --git a/server/src/com/cloud/storage/TemplateProfile.java b/server/src/com/cloud/storage/TemplateProfile.java index e3943d98dae..65c29f0be6c 100755 --- a/server/src/com/cloud/storage/TemplateProfile.java +++ b/server/src/com/cloud/storage/TemplateProfile.java @@ -46,6 +46,7 @@ public class TemplateProfile { VMTemplateVO template; String templateTag; Map details; + public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 7e560e380fa..9bb7bc7d6ad 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -61,7 +61,7 @@ import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; @Local(value=TemplateAdapter.class) -public class HypervisorTemplateAdapter extends TemplateAdapterBase implements TemplateAdapter { +public class HypervisorTemplateAdapter extends TemplateAdapterBase { private final static Logger s_logger = Logger.getLogger(HypervisorTemplateAdapter.class); @Inject DownloadMonitor _downloadMonitor; @Inject AgentManager _agentMgr; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index fbac9b40892..09cce637015 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -50,7 +50,6 @@ import org.apache.cloudstack.api.command.user.template.ListTemplatePermissionsCm import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd; import org.apache.cloudstack.api.command.user.template.UpdateTemplateCmd; import org.apache.cloudstack.api.command.user.template.UpdateTemplatePermissionsCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.CommandResult; 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.EndPoint; @@ -65,6 +64,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; From 9f7bad2cef25fdf02683f0f0e0f0e14084aefbbf Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 6 May 2013 18:26:33 -0700 Subject: [PATCH 112/303] fix creating snapshot --- .../storage/command/DownloadCommand.java | 1 + .../motion/AncientDataMotionStrategy.java | 2 +- .../cloudstack/storage/test/SnapshotTest.java | 352 +++++++++++++++++- .../storage/snapshot/SnapshotServiceImpl.java | 10 +- .../snapshot/XenserverSnapshotStrategy.java | 2 +- .../cloudstack/storage/LocalHostEndpoint.java | 24 +- .../ObjectInDataStoreManagerImpl.java | 4 + .../storage/volume/VolumeObject.java | 2 + .../storage/volume/VolumeServiceImpl.java | 27 +- .../resource/XenServerStorageResource.java | 52 +-- .../CloudStackPrimaryDataStoreDriverImpl.java | 4 +- .../SamplePrimaryDataStoreDriverImpl.java | 4 +- .../com/cloud/storage/VolumeManagerImpl.java | 1 + setup/db/db/schema-410to420.sql | 2 +- 14 files changed, 434 insertions(+), 53 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java index 5388f0a9ebd..7e3d65c7bde 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadCommand.java @@ -65,6 +65,7 @@ public class DownloadCommand extends AbstractDownloadCommand implements Internal } public DownloadCommand(TemplateObjectTO template, Long maxDownloadSizeInBytes) { + super(template.getName(), template.getOrigUrl(), template.getFormat(), template.getAccountId()); this._store = template.getDataStore(); this.installPath = template.getPath(); 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 index 32f9a9aa101..db3971c673e 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -370,7 +370,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { DataObject cacheData = null; try { - if (destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + if (needCacheStorage(srcData, destData)) { cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index afd63f5bfdd..203f762a0e4 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -18,6 +18,356 @@ */ package org.apache.cloudstack.storage.test; -public class SnapshotTest { +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; +import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.RemoteHostEndPoint; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.volume.db.VolumeDao2; +import org.apache.cloudstack.storage.volume.db.VolumeVO; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.host.Host; +import com.cloud.host.HostVO; +import com.cloud.host.Host.Type; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.org.Cluster.ClusterType; +import com.cloud.org.Managed.ManagedState; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; +import com.cloud.storage.Snapshot; +import com.cloud.storage.SnapshotVO; +import com.cloud.storage.Storage; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.utils.component.ComponentContext; + +@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +public class SnapshotTest extends CloudStackTestNGBase { + @Inject + ImageStoreDao imageStoreDao; + ImageStoreVO imageStore; + Long dcId; + Long clusterId; + Long podId; + HostVO host; + String primaryName = "my primary data store"; + DataStore primaryStore; + @Inject + HostDao hostDao; + @Inject + TemplateService imageService; + @Inject + VolumeService volumeService; + @Inject + VMTemplateDao imageDataDao; + @Inject + VolumeDao2 volumeDao; + @Inject + HostPodDao podDao; + @Inject + ClusterDao clusterDao; + @Inject + DataCenterDao dcDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + @Inject + DataStoreProviderManager dataStoreProviderMgr; + @Inject + TemplateDataStoreDao templateStoreDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + PrimaryDataStoreDao primaryDataStoreDao; + @Inject + AgentManager agentMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + ResourceManager resourceMgr; + @Inject + VolumeDataFactory volFactory; + @Inject SnapshotDataFactory snapshotFactory; + @Inject + List snapshotStrategies; + @Inject + SnapshotService snapshotSvr; + @Inject + SnapshotDao snapshotDao; + @Inject + EndPointSelector epSelector; + long primaryStoreId; + VMTemplateVO image; + String imageStoreName = "testImageStore"; + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + + host = hostDao.findByGuid(this.getHostGuid()); + if (host != null) { + dcId = host.getDataCenterId(); + clusterId = host.getClusterId(); + podId = host.getPodId(); + imageStore = this.imageStoreDao.findByName(imageStoreName); + } else { + //create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", + null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + //create pod + + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); + pod = podDao.persist(pod); + podId = pod.getId(); + //create xen cluster + ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); + cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setClusterType(ClusterType.CloudManaged); + cluster.setManagedState(ManagedState.Managed); + cluster = clusterDao.persist(cluster); + clusterId = cluster.getId(); + //create xen host + + host = new HostVO(this.getHostGuid()); + host.setName("devcloud xen host"); + host.setType(Host.Type.Routing); + host.setPrivateIpAddress(this.getHostIp()); + host.setDataCenterId(dc.getId()); + host.setVersion("6.0.1"); + host.setAvailable(true); + host.setSetup(true); + host.setPodId(podId); + host.setLastPinged(0); + host.setResourceState(ResourceState.Enabled); + host.setHypervisorType(HypervisorType.XenServer); + host.setClusterId(cluster.getId()); + + host = hostDao.persist(host); + + imageStore = new ImageStoreVO(); + imageStore.setName(imageStoreName); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore.setProtocol("nfs"); + imageStore = imageStoreDao.persist(imageStore); + } + + image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + + image = imageDataDao.persist(image); + + /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); + + templateStore.setDataStoreId(imageStore.getId()); + templateStore.setDownloadPercent(100); + templateStore.setDownloadState(Status.DOWNLOADED); + templateStore.setDownloadUrl(imageStore.getUrl()); + templateStore.setInstallPath(this.getImageInstallPath()); + templateStore.setTemplateId(image.getId()); + templateStoreDao.persist(templateStore);*/ + + + DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); + TemplateInfo template = templateFactory.getTemplate(image.getId()); + DataObject templateOnStore = store.create(template); + TemplateObjectTO to = new TemplateObjectTO(); + to.setPath(this.getImageInstallPath()); + CopyCmdAnswer answer = new CopyCmdAnswer(to); + templateOnStore.processEvent(Event.CreateOnlyRequested); + templateOnStore.processEvent(Event.OperationSuccessed, answer); + + + } + + @Override + protected void injectMockito() { + List hosts = new ArrayList(); + hosts.add(this.host); + Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); + + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + } + + public DataStore createPrimaryDataStore() { + try { + String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString(); + List pools = primaryDataStoreDao.findPoolByName(this.primaryName); + if (pools.size() > 0) { + return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); + } + + /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); + Map params = new HashMap(); + URI uri = new URI(this.getPrimaryStorageUrl()); + params.put("url", this.getPrimaryStorageUrl()); + params.put("server", uri.getHost()); + params.put("path", uri.getPath()); + params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); + params.put("zoneId", dcId); + params.put("clusterId", clusterId); + params.put("name", this.primaryName); + params.put("port", 1); + params.put("podId", this.podId); + params.put("roles", DataStoreRole.Primary.toString()); + params.put("uuid", uuid); + params.put("providerName", String.valueOf(provider.getName())); + + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + DataStore store = lifeCycle.initialize(params); + ClusterScope scope = new ClusterScope(clusterId, podId, dcId); + lifeCycle.attachCluster(store, scope);*/ + + StoragePoolVO pool = new StoragePoolVO(); + pool.setClusterId(clusterId); + pool.setDataCenterId(dcId); + URI uri = new URI(this.getPrimaryStorageUrl()); + pool.setHostAddress(uri.getHost()); + pool.setPath(uri.getPath()); + pool.setPort(0); + pool.setName(this.primaryName); + pool.setUuid(this.getPrimaryStorageUuid()); + pool.setStatus(StoragePoolStatus.Up); + pool.setPoolType(StoragePoolType.NetworkFilesystem); + pool.setPodId(podId); + pool.setScope(ScopeType.CLUSTER); + pool.setStorageProviderName("cloudstack primary data store provider"); + pool = this.primaryStoreDao.persist(pool); + DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + return store; + } catch (Exception e) { + return null; + } + } + + private SnapshotVO createSnapshotInDb(VolumeInfo volume) { + Snapshot.Type snapshotType = Snapshot.Type.MANUAL; + SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID().toString(), + (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), HypervisorType.XenServer); + return this.snapshotDao.persist(snapshotVO); + } + + private VolumeVO createVolume(Long templateId, long dataStoreId) { + VolumeVO volume = new VolumeVO(1000, new RootDisk().toString(), UUID.randomUUID().toString(), templateId); + volume.setDataCenterId(this.dcId); + volume.setPoolId(dataStoreId); + volume = volumeDao.persist(volume); + return volume; + } + + + public VolumeInfo createCopyBaseImage() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId())); + + VolumeApiResult result; + try { + result = future.get(); + return result.getVolume(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + @Test + public void createSnapshot() { + VolumeInfo vol = createCopyBaseImage(); + SnapshotVO snapshotVO = createSnapshotInDb(vol); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + strategy.takeSnapshot(snapshot); + } + } + } + + //@Test + public void testCreateDataDisk() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + this.volumeService.createVolumeAsync(volInfo, primaryStore); + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 79237c4ffc6..12d80576c85 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -42,6 +42,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; @@ -170,6 +171,7 @@ public class SnapshotServiceImpl implements SnapshotService { try { snapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); + snapshot.processEvent(Snapshot.Event.OperationSucceeded); } catch (Exception e) { s_logger.debug("Failed to create snapshot: ", e); snapResult.setResult(e.toString()); @@ -323,12 +325,8 @@ public class SnapshotServiceImpl implements SnapshotService { } try { - BackupSnapshotAnswer answer = (BackupSnapshotAnswer)result.getAnswer(); - - DataObjectInStore dataInStore = objInStoreMgr.findObject(destSnapshot, destSnapshot.getDataStore()); - dataInStore.setInstallPath(answer.getBackupSnapshotName()); - objInStoreMgr.update(destSnapshot, Event.OperationSuccessed); - + CopyCmdAnswer answer = (CopyCmdAnswer)result.getAnswer(); + destSnapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), answer); future.complete(snapResult); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index df2264a3a4a..271bee5cf8b 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -56,7 +56,7 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { @Override public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { SnapshotInfo parentSnapshot = snapshot.getParent(); - if (parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) { + if (parentSnapshot != null && parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) { s_logger.debug("backup an empty snapshot"); //don't need to backup this snapshot SnapshotDataStoreVO parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 170772596a0..1ae13b630d0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -63,19 +63,31 @@ public class LocalHostEndpoint implements EndPoint { private class CmdRunner2 implements Runnable { final Command cmd; - final AsyncCompletionCallback callback; - public CmdRunner2(Command cmd, AsyncCompletionCallback callback) { + final Listener listener; + public CmdRunner2(Command cmd, Listener listener) { this.cmd = cmd; - this.callback = callback; + this.listener = listener; } @Override public void run() { try { DownloadAnswer answer = (DownloadAnswer) sendMessage(cmd); - callback.complete(answer); + Answer[] answers = new Answer[1]; + answers[0] = answer; + listener.processAnswers(getId(), 0, answers); + if (listener instanceof DownloadListener) { + DownloadListener dwldListener = (DownloadListener)listener; + dwldListener.getCallback().complete(answer); + } } catch (Exception ex) { DownloadAnswer fail = new DownloadAnswer("Error in handling DownloadCommand : " + ex.getMessage(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); - callback.complete(fail); + Answer[] answers = new Answer[1]; + answers[0] = fail; + listener.processAnswers(getId(), 0, answers); + if (listener instanceof DownloadListener) { + DownloadListener dwldListener = (DownloadListener)listener; + dwldListener.getCallback().complete(fail); + } } } } @@ -89,7 +101,7 @@ public class LocalHostEndpoint implements EndPoint { public void sendMessageAsyncWithListener(Command cmd, Listener listner) { if (listner instanceof DownloadListener) { DownloadListener listener = (DownloadListener)listner; - executor.schedule(new CmdRunner2(cmd, listener.getCallback()), 10, TimeUnit.SECONDS); + executor.schedule(new CmdRunner2(cmd, listener), 10, TimeUnit.SECONDS); } } public ServerResource getResource() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 1d891e53ddc..763d2cabf7c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -227,6 +227,8 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { this.stateMachines.transitTo(obj, event, null, templatePoolDao); + } else if (data.getType() == DataObjectType.SNAPSHOT && data.getDataStore().getRole() == DataStoreRole.Primary) { + this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao); } else { throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); } @@ -270,6 +272,8 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } } else if (type == DataObjectType.TEMPLATE && role == DataStoreRole.Primary) { vo = templatePoolDao.findByPoolTemplate(dataStoreId, objId); + } else if (type == DataObjectType.SNAPSHOT && role == DataStoreRole.Primary) { + vo = snapshotDataStoreDao.findByStoreSnapshot(role, dataStoreId, objId); } else { s_logger.debug("Invalid data or store type: " + type + " " + role); throw new CloudRuntimeException("Invalid data or store type: " + type + " " + role); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 1aee5d304a0..be7bd12104d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -380,6 +380,7 @@ public class VolumeObject implements VolumeInfo { VolumeObjectTO newVol = (VolumeObjectTO)cpyAnswer.getNewData(); vol.setPath(newVol.getPath()); vol.setSize(newVol.getSize()); + vol.setPoolId(this.getDataStore().getId()); volumeDao.update(vol.getId(), vol); } else if (answer instanceof CreateObjectAnswer) { CreateObjectAnswer createAnswer =(CreateObjectAnswer)answer; @@ -387,6 +388,7 @@ public class VolumeObject implements VolumeInfo { VolumeVO vol = this.volumeDao.findById(this.getId()); vol.setPath(newVol.getPath()); vol.setSize(newVol.getSize()); + vol.setPoolId(this.getDataStore().getId()); volumeDao.update(vol.getId(), vol); } } else if (this.dataStore.getRole() == DataStoreRole.Image) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 74e01be4892..57dd6608854 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -358,17 +358,28 @@ public class VolumeServiceImpl implements VolumeService { templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); } catch (Exception e) { try { - templateOnPrimaryStoreObj = waitForTemplateDownloaded(dataStore, template); - } finally { - if (templateOnPrimaryStoreObj == null) { - VolumeApiResult result = new VolumeApiResult(volume); - result.setResult(e.toString()); - caller.complete(result); - return; - } + templateOnPrimaryStoreObj = waitForTemplateDownloaded(dataStore, template); + } catch(Exception e1) { + s_logger.debug("wait for template:" + template.getId() + " downloading finished, but failed"); + VolumeApiResult result = new VolumeApiResult(volume); + result.setResult(e1.toString()); + caller.complete(result); + return; + } + if (templateOnPrimaryStoreObj == null) { + VolumeApiResult result = new VolumeApiResult(volume); + result.setResult("wait for template:" + template.getId() + " downloading finished, but failed"); + caller.complete(result); + return; + } else { + s_logger.debug("waiting for template:" + template.getId() + " downloading finished, success"); + VolumeApiResult result = new VolumeApiResult(volume); + future.complete(result); + return; } } + try { motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); } catch (Exception e) { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index 42099499ce5..ab01c7262e8 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -170,35 +170,35 @@ public class XenServerStorageResource { String snapshotUUID = null; try { - String volumeUUID = snapshotTO.getVolume().getPath(); - VDI volume = VDI.getByUuid(conn, volumeUUID); + String volumeUUID = snapshotTO.getVolume().getPath(); + VDI volume = VDI.getByUuid(conn, volumeUUID); - VDI snapshot = volume.snapshot(conn, new HashMap()); + VDI snapshot = volume.snapshot(conn, new HashMap()); - if (snapshotName != null) { - snapshot.setNameLabel(conn, snapshotName); + if (snapshotName != null) { + snapshot.setNameLabel(conn, snapshotName); + } + + snapshotUUID = snapshot.getUuid(conn); + String preSnapshotUUID = snapshotTO.getParentSnapshotPath(); + //check if it is a empty snapshot + if( preSnapshotUUID != null) { + SR sr = volume.getSR(conn); + String srUUID = sr.getUuid(conn); + String type = sr.getType(conn); + Boolean isISCSI = IsISCSI(type); + String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI); + + String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI); + if( snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) { + // this is empty snapshot, remove it + snapshot.destroy(conn); + snapshotUUID = preSnapshotUUID; } - - snapshotUUID = snapshot.getUuid(conn); - String preSnapshotUUID = snapshotTO.getPath(); - //check if it is a empty snapshot - if( preSnapshotUUID != null) { - SR sr = volume.getSR(conn); - String srUUID = sr.getUuid(conn); - String type = sr.getType(conn); - Boolean isISCSI = IsISCSI(type); - String snapshotParentUUID = getVhdParent(conn, srUUID, snapshotUUID, isISCSI); - - String preSnapshotParentUUID = getVhdParent(conn, srUUID, preSnapshotUUID, isISCSI); - if( snapshotParentUUID != null && snapshotParentUUID.equals(preSnapshotParentUUID)) { - // this is empty snapshot, remove it - snapshot.destroy(conn); - snapshotUUID = preSnapshotUUID; - } - } - SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(snapshotUUID); - return new CreateObjectAnswer(newSnapshot); + } + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + newSnapshot.setPath(snapshotUUID); + return new CreateObjectAnswer(newSnapshot); } catch (XenAPIException e) { details += ", reason: " + e.toString(); s_logger.warn(details, e); diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 6acded982a9..912a11ee66e 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -190,7 +190,8 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri DataTO snapshotTO = snapshot.getTO(); CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO); - Answer answer = storageMgr.sendToPool((StoragePool)snapshot.getDataStore(), null, cmd); + EndPoint ep = this.epSelecotor.select(snapshot); + Answer answer = ep.sendMessage(cmd); result = new CreateCmdResult(null, answer); if (answer != null && !answer.getResult()) { @@ -198,6 +199,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri } callback.complete(result); + return; } catch (Exception e) { s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); result = new CreateCmdResult(null, null); diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index c8a2a0c2e55..f530362896c 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -105,14 +105,14 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver @Override public void deleteAsync(DataObject vo, AsyncCompletionCallback callback) { - DeleteCommand cmd = new DeleteCommand(vo.getUri()); + /*DeleteCommand cmd = new DeleteCommand(vo.getUri()); EndPoint ep = selector.select(vo); AsyncRpcConext context = new AsyncRpcConext(callback); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().deleteCallback(null, null)) .setContext(context); - ep.sendMessageAsync(cmd, caller); + ep.sendMessageAsync(cmd, caller);*/ } public Void deleteCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 23e329558c7..39d3ce20c16 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -2487,6 +2487,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { payload.setSnapshotId(snapshotId); payload.setSnapshotPolicyId(policyId); payload.setAccount(account); + volume.addPayload(payload); return this.volService.takeSnapshot(volume); } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index ad8bdc44bd4..a88af23e81e 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -170,7 +170,7 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `parent_snapshot_id` bigint unsigned DEFAULT 0, `install_path` varchar(255), `state` varchar(255) NOT NULL, - `destroyed` tinyint(1) COMMENT 'indicates whether the snapshot_store entry was destroyed by the user or not', + `removed` datetime COMMENT 'date removed if not null', `update_count` bigint unsigned, `updated` datetime, PRIMARY KEY (`id`), From 1b8e7aba739331ec4514ca37b1123df3219b4744 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 6 May 2013 18:28:47 -0700 Subject: [PATCH 113/303] uncomment out template sync --- .../apache/cloudstack/storage/image/TemplateServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 8e3f892cf51..c7eb069f575 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -377,7 +377,7 @@ public class TemplateServiceImpl implements TemplateService { } } - /* for (String uniqueName : templateInfos.keySet()) { + for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. @@ -396,7 +396,7 @@ public class TemplateServiceImpl implements TemplateService { } } - }*/ + } } From 0e28772957d2e317bc3f0197c2e567ce1c914123 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 6 May 2013 19:04:41 -0700 Subject: [PATCH 114/303] fix race condition, when multiple vms on the same templates are started at the same time --- .../cloudstack/storage/volume/VolumeServiceImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 57dd6608854..833f079c382 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -363,18 +363,17 @@ public class VolumeServiceImpl implements VolumeService { s_logger.debug("wait for template:" + template.getId() + " downloading finished, but failed"); VolumeApiResult result = new VolumeApiResult(volume); result.setResult(e1.toString()); - caller.complete(result); + future.complete(result); return; } if (templateOnPrimaryStoreObj == null) { VolumeApiResult result = new VolumeApiResult(volume); result.setResult("wait for template:" + template.getId() + " downloading finished, but failed"); - caller.complete(result); + future.complete(result); return; } else { s_logger.debug("waiting for template:" + template.getId() + " downloading finished, success"); - VolumeApiResult result = new VolumeApiResult(volume); - future.complete(result); + createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future); return; } } From 26424ff2a8b74b514cec1b513093b9893659dbfc Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 22:14:49 -0700 Subject: [PATCH 115/303] Make url in AddImageStoreCmd not required since S3 does not have url. --- .../api/command/admin/storage/AddImageStoreCmd.java | 2 +- .../storage/image/datastore/ImageStoreHelper.java | 5 ++++- .../datastore/lifecycle/S3ImageStoreLifeCycleImpl.java | 2 ++ .../datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java | 1 - server/src/com/cloud/storage/s3/S3ManagerImpl.java | 8 ++++---- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index 8349774cbaf..08112f0aab0 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -44,7 +44,7 @@ public class AddImageStoreCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// - @Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=true, description="the URL for the image store") + @Parameter(name=ApiConstants.URL, type=CommandType.STRING, description="the URL for the image store") private String url; @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index fe6e94f2853..d0dfd55ff37 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -70,7 +70,6 @@ public class ImageStoreHelper { return store; } store = new ImageStoreVO(); - store.setName((String)params.get("name")); store.setProtocol((String)params.get("protocol")); store.setProviderName((String)params.get("providerName")); store.setScope((ScopeType)params.get("scope")); @@ -82,6 +81,10 @@ public class ImageStoreHelper { store.setUuid(UUID.randomUUID().toString()); } store.setUrl((String)params.get("url")); + store.setName((String)params.get("name")); + if ( store.getName() == null ){ + store.setName(store.getUuid()); + } store.setRole((DataStoreRole)params.get("role")); store = imageStoreDao.persist(store); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java index 05c9e37aca4..1b5e2d57344 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -91,6 +91,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { s_logger.info("Trying to add a S3 store in data center " + dcId); + /* try{ // verify S3 parameters _s3Mgr.verifyS3Fields(details); @@ -98,6 +99,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { catch (DiscoveryException ex){ throw new InvalidParameterValueException("failed to verify S3 parameters!"); } + */ Map imageStoreParameters = new HashMap(); imageStoreParameters.put("name", url); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java index 20e0939b9fe..411e052440f 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -90,7 +90,6 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { // just need to insert an entry in DB Map imageStoreParameters = new HashMap(); - imageStoreParameters.put("name", url); imageStoreParameters.put("zoneId", dcId); imageStoreParameters.put("url", url); imageStoreParameters.put("protocol", "http"); diff --git a/server/src/com/cloud/storage/s3/S3ManagerImpl.java b/server/src/com/cloud/storage/s3/S3ManagerImpl.java index 1e8ad4f54ed..2edf2326b59 100644 --- a/server/src/com/cloud/storage/s3/S3ManagerImpl.java +++ b/server/src/com/cloud/storage/s3/S3ManagerImpl.java @@ -258,10 +258,10 @@ public class S3ManagerImpl extends ManagerBase implements S3Manager { params.get(ApiConstants.S3_SECRET_KEY), params.get(ApiConstants.S3_END_POINT), params.get(ApiConstants.S3_BUCKET_NAME), - Boolean.valueOf(params.get(ApiConstants.S3_HTTPS_FLAG)), - Integer.valueOf(params.get(ApiConstants.S3_CONNECTION_TIMEOUT)), - Integer.valueOf(params.get(ApiConstants.S3_MAX_ERROR_RETRY)), - Integer.valueOf(params.get(ApiConstants.S3_SOCKET_TIMEOUT)), now()); + params.get(ApiConstants.S3_HTTPS_FLAG) == null ? false : Boolean.valueOf(params.get(ApiConstants.S3_HTTPS_FLAG)), + params.get(ApiConstants.S3_CONNECTION_TIMEOUT) == null ? null : Integer.valueOf(params.get(ApiConstants.S3_CONNECTION_TIMEOUT)), + params.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null : Integer.valueOf(params.get(ApiConstants.S3_MAX_ERROR_RETRY)), + params.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null : Integer.valueOf(params.get(ApiConstants.S3_SOCKET_TIMEOUT)), now()); this.validateFields(s3VO); From 41272c976e5ffddacddf2fdff9d00a065da0c8a3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 6 May 2013 23:02:28 -0700 Subject: [PATCH 116/303] Add DeleteTemplate unit test. --- .../cloudstack/storage/test/TemplateTest.java | 21 ++++++++++++++++++- .../integration-test/test/resource/testng.xml | 4 ++-- .../storage/download/DownloadListener.java | 2 +- .../template/HypervisorTemplateAdapter.java | 21 ++++++++++++------- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index 7749c076458..a38b91c3252 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -61,7 +61,7 @@ public class TemplateTest extends CloudStackTestNGBase { @Inject DownloadMonitorImpl downloadMonitor; - + long dcId; long templateId; @@ -134,4 +134,23 @@ public class TemplateTest extends CloudStackTestNGBase { } } + // @Test + public void deleteTemplate() { + TemplateInfo template = templateFactory.getTemplate(templateId); + DataStore store = dataStoreMgr.getImageStore(dcId); + AsyncCallFuture future = new AsyncCallFuture(); + templateSvr.deleteTemplateAsync(template); + try { + TemplateApiResult result = future.get(); + assertTrue(result.isSuccess(), "failed to delete template: " + result.getResult()); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } + } } diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index dbadae1dde1..4b074487b4c 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -27,8 +27,8 @@ - - + + diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 84c51b1ffdb..001b45dc1c4 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -99,7 +99,7 @@ public class DownloadListener implements Listener { public static final Logger s_logger = Logger.getLogger(DownloadListener.class.getName()); public static final int SMALL_DELAY = 100; - public static final long STATUS_POLL_INTERVAL = 300000L; //10000L; + public static final long STATUS_POLL_INTERVAL = 10000L; public static final String DOWNLOADED=Status.DOWNLOADED.toString(); public static final String NOT_DOWNLOADED=Status.NOT_DOWNLOADED.toString(); diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 973b558e162..35bc5e5d678 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -193,13 +193,20 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { } } - protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher callback, CreateTemplateContext context) { - TemplateInfo template = context.template; - VMTemplateVO tmplt = this._tmpltDao.findById(template.getId()); - long accountId = tmplt.getAccountId(); - if (template.getSize() != null) { - _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize()); + protected Void createTemplateAsyncCallBack(AsyncCallbackDispatcher callback, + CreateTemplateContext context) { + TemplateApiResult result = callback.getResult(); + TemplateInfo template = context.template; + if (result.isFailed()) { + // failed in creating template, we need to remove those already + // populated template entry + _tmpltDao.remove(template.getId()); + } else { + VMTemplateVO tmplt = this._tmpltDao.findById(template.getId()); + long accountId = tmplt.getAccountId(); + if (template.getSize() != null) { + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.secondary_storage, template.getSize()); + } } return null; From 9f5d3c276dae4b5b65109234465637f04b3defea Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 7 May 2013 10:54:05 -0700 Subject: [PATCH 117/303] CLOUDSTACK-2351: object store - UI - Infrastructure menu - secondary storages - add secondary storage - implement provider S3. --- ui/scripts/system.js | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index d791f10e7d5..0ecd935f04a 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -290,8 +290,8 @@ }, success: function(json) { dataFns.systemVmCount($.extend(data, { - secondaryStorageCount: json.listhostsresponse.count ? - json.listhostsresponse.count : 0 + secondaryStorageCount: json.listimagestoreresponse.imagestore ? + json.listimagestoreresponse.count : 0 })); } }); @@ -5472,10 +5472,10 @@ '&name=' + args.filterBy.search.value : ''; $.ajax({ - url: createURL('listHosts' + searchByArgs), - data: { type: 'SecondaryStorage', page: args.page, pageSize: pageSize, listAll: true }, + url: createURL('listImageStores' + searchByArgs), + data: { type: 'image', page: args.page, pageSize: pageSize, listAll: true }, success: function (json) { - args.response.success({ data: json.listhostsresponse.host }); + args.response.success({ data: json.listimagestoreresponse.imagestore }); }, error: function (json) { args.response.error(parseXMLHttpResponse(json)); @@ -10344,7 +10344,7 @@ dataType: "json", async: true, success: function(json) { - var items = json.listhostsresponse.host; + var items = json.listimagestoreresponse.imagestore; args.response.success({ actionFilter: secondarystorageActionfilter, data:items @@ -10563,15 +10563,23 @@ $.ajax({ url: createURL('addImageStore'), data: { - provider: args.data.provider, - accesskey: args.data.accesskey, - secretkey: args.data.secretkey, - bucket: args.data.bucket, - endpoint: args.data.endpoint, - usehttps: (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false'), - connectiontimeout: args.data.connectiontimeout, - maxerrorretry: args.data.maxerrorretry, - sockettimeout: args.data.sockettimeout + provider: args.data.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.bucket, + 'details[3].key': 'endpoint', + 'details[3].value': args.data.endpoint, + 'details[4].key': 'usehttps', + 'details[4].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false'), + 'details[5].key': 'connectiontimeout', + 'details[5].value': args.data.connectiontimeout, + 'details[6].key': 'maxerrorretry', + 'details[6].value': args.data.maxerrorretry, + 'details[7].key': 'sockettimeout', + 'details[7].value': args.data.sockettimeout }, success: function(json) { havingS3 = true; @@ -10673,11 +10681,11 @@ dataProvider: function(args) { $.ajax({ - url: createURL("listHosts&type=SecondaryStorage&id=" + args.context.secondarystorages[0].id), + url: createURL("listImageStores&type=image&id=" + args.context.secondarystorages[0].id), dataType: "json", async: true, success: function(json) { - var item = json.listhostsresponse.host[0]; + var item = json.listimagestoreresponse.imagestore[0]; args.response.success({ actionFilter: secondarystorageActionfilter, data:item From 79935f6eee6001e8aac5ea1a2c23b7e1bf7f695f Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 7 May 2013 11:11:30 -0700 Subject: [PATCH 118/303] CLOUDSTACK-2351: object store - UI - zone wizard - add secondary storage step - replace addSecondaryStorage API with new API addImageStore. --- ui/scripts/zoneWizard.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 8add9bb085e..96f9a5b86e9 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -3384,13 +3384,19 @@ var path = args.data.secondaryStorage.path; var url = nfsURL(nfs_server, path); + var data = { + provider: 'NFS', + zoneid: args.data.returnedZone.id, + url: url + }; + $.ajax({ - url: createURL("addSecondaryStorage&zoneId=" + args.data.returnedZone.id + "&url=" + todb(url)), - dataType: "json", + url: createURL('addImageStore'), + data: data, success: function(json) { complete({ data: $.extend(args.data, { - returnedSecondaryStorage: json.addsecondarystorageresponse.secondarystorage + returnedSecondaryStorage: json.addimagestoreresponse.secondarystorage }) }); }, From d9733e900dbfa73035adaf4194978218727ffbc3 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 7 May 2013 11:38:31 -0700 Subject: [PATCH 119/303] CLOUDSTACK-2351: object store - UI - infrastructure menu - secondary storages - detailView - delete action - replace deleteHost API with new API deleteImageStore. --- ui/scripts/system.js | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 0ecd935f04a..abf41a9f73c 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -224,16 +224,7 @@ dataFns.hostCount($.extend(data, { clusterCount: json.listclustersresponse.count ? json.listclustersresponse.count : 0 - })); - - //comment the 4 lines above and uncomment the following 4 lines if listHosts API still responds slowly. - - /* - dataFns.primaryStorageCount($.extend(data, { - clusterCount: json.listclustersresponse.count ? - json.listclustersresponse.count : 0 - })); - */ + })); } }); }, @@ -266,16 +257,7 @@ dataFns.secondaryStorageCount($.extend(data, { primaryStorageCount: json.liststoragepoolsresponse.count ? json.liststoragepoolsresponse.count : 0 - })); - - //comment the 4 lines above and uncomment the following 4 lines if listHosts API still responds slowly. - - /* - dataFns.systemVmCount($.extend(data, { - primaryStorageCount: json.liststoragepoolsresponse.count ? - json.liststoragepoolsresponse.count : 0 - })); - */ + })); } }); }, @@ -9282,8 +9264,7 @@ url: createURL("deleteHost&id=" + args.context.hosts[0].id + array1.join("")), dataType: "json", async: true, - success: function(json) { - //{ "deletehostresponse" : { "success" : "true"} } + success: function(json) { args.response.success({data:{}}); } }); @@ -10651,9 +10632,10 @@ }, action: function(args) { $.ajax({ - url: createURL("deleteHost&id=" + args.context.secondarystorages[0].id), - dataType: "json", - async: true, + url: createURL('deleteImageStore'), + data: { + id: args.context.secondarystorages[0].id + }, success: function(json) { args.response.success(); } @@ -10681,7 +10663,7 @@ dataProvider: function(args) { $.ajax({ - url: createURL("listImageStores&type=image&id=" + args.context.secondarystorages[0].id), + url: createURL("listImageStores&id=" + args.context.secondarystorages[0].id), dataType: "json", async: true, success: function(json) { From e0fa8e1e936dcc21c8b3451249ed65db19cf7cfa Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 7 May 2013 12:04:07 -0700 Subject: [PATCH 120/303] CLOUDSTACK-2351: object store - UI - cloudstack.js - replace listS3s, listSwiftsAPI with new API listImageStores. --- ui/scripts/cloudStack.js | 32 ++++++++++++++++++++------------ ui/scripts/system.js | 7 +++---- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index 985627b824e..1eb02b6b525 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -186,22 +186,26 @@ if (userValid && isAdmin()) { $.ajax({ - url: createURL("listSwifts"), - dataType: "json", + url: createURL("listImageStores"), + data: { + provider: 'Swift' + }, async: false, success: function(json) { - var items = json.listswiftsresponse.swift; + var items = json.listimagestoreresponse.imagestore; if(items != null && items.length > 0) havingSwift = true; } }); if (havingSwift == false) { $.ajax({ - url: createURL("listS3s"), - dataType: "json", + url: createURL("listImageStores"), + data: { + provider: 'S3' + }, async: false, success: function(json) { - var items = json.lists3sresponse.s3; + var items = json.listimagestoreresponse.imagestore; if (items != null && items.length > 0) { havingS3 = true; } @@ -328,22 +332,26 @@ if (isAdmin()) { $.ajax({ - url: createURL("listSwifts"), - dataType: "json", + url: createURL("listImageStores"), + data:{ + provider: 'Swift' + }, async: false, success: function(json) { - var items = json.listswiftsresponse.swift; + var items = json.listimagestoreresponse.imagestore; if(items != null && items.length > 0) havingSwift = true; } }); if (havingSwift = false) { $.ajax({ - url: createURL("listS3s"), - dataType: "json", + url: createURL("listImageStores"), + data: { + provider: 'S3' + }, async: false, success: function(json) { - var items = json.lists3sresponse.s3; + var items = json.listimagestoreresponse.imagestore; if (items != null && items.length > 0) { havingS3 = true; } diff --git a/ui/scripts/system.js b/ui/scripts/system.js index abf41a9f73c..fedef35a14f 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -265,8 +265,7 @@ secondaryStorageCount: function(data) { $.ajax({ url: createURL('listImageStores'), - data: { - type: 'image', + data: { page: 1, pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }, @@ -5455,7 +5454,7 @@ $.ajax({ url: createURL('listImageStores' + searchByArgs), - data: { type: 'image', page: args.page, pageSize: pageSize, listAll: true }, + data: { page: args.page, pageSize: pageSize, listAll: true }, success: function (json) { args.response.success({ data: json.listimagestoreresponse.imagestore }); }, @@ -10321,7 +10320,7 @@ } } $.ajax({ - url: createURL("listImageStores&type=image&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + url: createURL("listImageStores&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: "json", async: true, success: function(json) { From e6598193815b9e9e35f98db3ef44d3d621db03f5 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Tue, 7 May 2013 12:35:35 -0700 Subject: [PATCH 121/303] CLOUDSTACK-2351: object store - UI - zone wizard - add secondary storage step - implement provider S3, Swift. --- ui/scripts/zoneWizard.js | 245 ++++++++++++++++++++++++++++++++++----- 1 file changed, 218 insertions(+), 27 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 96f9a5b86e9..03339fb8f99 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -1502,7 +1502,108 @@ } }, secondaryStorage: { - fields: { + fields: { + provider: { + label: 'Provider', + select: function(args){ + $.ajax({ + url: createURL('listStorageProviders'), + data: { + type: 'image' + }, + success: function(json){ + var objs = json.liststorageprovidersresponse.dataStoreProvider; + var items = []; + if(objs != null) { + for(var i = 0; i < objs.length; i++){ + if(objs[i].name == 'NFS') + items.unshift({id: objs[i].name, description: objs[i].name}); + else + items.push({id: objs[i].name, description: objs[i].name}); + } + } + args.response.success({ + data: items + }); + + args.$select.change(function() { + var $form = $(this).closest('form'); + if($(this).val() == "NFS") { + //NFS + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if ($(this).val() == "S3") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); + $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); + $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); + $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); + $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); + $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if($(this).val() == "Swift") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + //Swift + $form.find('.form-item[rel=url]').css('display', 'inline-block'); + $form.find('.form-item[rel=account]').css('display', 'inline-block'); + $form.find('.form-item[rel=username]').css('display', 'inline-block'); + $form.find('.form-item[rel=key]').css('display', 'inline-block'); + } + }); + + args.$select.change(); + } + }); + } + }, + + + //NFS (begin) nfsServer: { label: 'label.nfs.server', validation: { required: true } @@ -1510,7 +1611,34 @@ path: { label: 'label.path', validation: { required: true } - } + }, + //NFS (end) + + + //S3 (begin) + accesskey: { label: 'label.s3.access_key', validation: { required: true } }, + secretkey: { label: 'label.s3.secret_key', validation: { required: true} }, + bucket: { label: 'label.s3.bucket', validation: { required: true} }, + endpoint: { label: 'label.s3.endpoint' }, + usehttps: { + label: 'label.s3.use_https', + isEditable: true, + isBoolean: true, + isChecked: true, + converter:cloudStack.converters.toBooleanText + }, + connectiontimeout: { label: 'label.s3.connection_timeout' }, + maxerrorretry: { label: 'label.s3.max_error_retry' }, + sockettimeout: { label: 'label.s3.socket_timeout' }, + //S3 (end) + + + //Swift (begin) + url: { label: 'label.url', validation: { required: true } }, + account: { label: 'label.account' }, + username: { label: 'label.username' }, + key: { label: 'label.key' } + //Swift (end) } } }, @@ -3380,31 +3508,94 @@ addSecondaryStorage: function(args) { message(dictionary['message.creating.secondary.storage']); - var nfs_server = args.data.secondaryStorage.nfsServer; - var path = args.data.secondaryStorage.path; - var url = nfsURL(nfs_server, path); - - var data = { - provider: 'NFS', - zoneid: args.data.returnedZone.id, - url: url - }; - - $.ajax({ - url: createURL('addImageStore'), - data: data, - success: function(json) { - complete({ - data: $.extend(args.data, { - returnedSecondaryStorage: json.addimagestoreresponse.secondarystorage - }) - }); - }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); - } - }); + if(args.data.secondaryStorage.provider == 'NFS') { + var nfs_server = args.data.secondaryStorage.nfsServer; + var path = args.data.secondaryStorage.path; + var url = nfsURL(nfs_server, path); + + var data = { + provider: 'NFS', + zoneid: args.data.returnedZone.id, + url: url + }; + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + complete({ + data: $.extend(args.data, { + returnedSecondaryStorage: json.addimagestoreresponse.secondarystorage + }) + }); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); + } + }); + } + else if(args.data.secondaryStorage.provider == 'S3') { + $.ajax({ + url: createURL('addImageStore'), + data: { + provider: args.data.secondaryStorage.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.secondaryStorage.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secondaryStorage.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.secondaryStorage.bucket, + 'details[3].key': 'endpoint', + 'details[3].value': args.data.secondaryStorage.endpoint, + 'details[4].key': 'usehttps', + 'details[4].value': (args.data.secondaryStorage.usehttps != null && args.data.secondaryStorage.usehttps == 'on' ? 'true' : 'false'), + 'details[5].key': 'connectiontimeout', + 'details[5].value': args.data.secondaryStorage.connectiontimeout, + 'details[6].key': 'maxerrorretry', + 'details[6].value': args.data.secondaryStorage.maxerrorretry, + 'details[7].key': 'sockettimeout', + 'details[7].value': args.data.secondaryStorage.sockettimeout + }, + success: function(json) { + complete({ + data: $.extend(args.data, { + returnedSecondaryStorage: json.addimagestoreresponse.secondarystorage + }) + }); + }, + error: function(json) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); + } + }); + } + else if(args.data.secondaryStorage.provider == 'Swift') { + $.ajax({ + url: createURL('addImageStore'), + data: { + provider: args.data.secondaryStorage.provider, + url: args.data.secondaryStorage.url, + 'details[0].key': 'account', + 'details[0].value': args.data.secondaryStorage.account, + 'details[1].key': 'username', + 'details[1].value': args.data.secondaryStorage.username, + 'details[2].key': 'key', + 'details[2].value': args.data.secondaryStorage.key + }, + success: function(json) { + complete({ + data: $.extend(args.data, { + returnedSecondaryStorage: json.addimagestoreresponse.secondarystorage + }) + }); + }, + error: function(json) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); + } + }); + } } }; From 3315b23595629b963d40650dabe81ff0e3543057 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 13:34:27 -0700 Subject: [PATCH 122/303] Relax url port validation and some MockLocalNfsSecondaryStorageResource fix. --- .../storage/template/DownloadManager.java | 2 +- .../storage/template/DownloadManagerImpl.java | 30 +++++++------------ .../template/HttpTemplateDownloader.java | 4 +-- .../MockLocalNfsSecondaryStorageResource.java | 15 ++++++++++ .../storage/test/CloudStackTestNGBase.java | 15 ++++++++-- .../cloudstack/storage/test/TemplateTest.java | 1 + .../integration-test/test/resource/testng.xml | 4 ++- .../com/cloud/storage/VolumeManagerImpl.java | 18 +++++------ .../template/HypervisorTemplateAdapter.java | 4 +-- utils/src/com/cloud/utils/UriUtils.java | 4 +-- 10 files changed, 59 insertions(+), 38 deletions(-) diff --git a/core/src/com/cloud/storage/template/DownloadManager.java b/core/src/com/cloud/storage/template/DownloadManager.java index 1897afd9c00..42ffe2ac3f9 100644 --- a/core/src/com/cloud/storage/template/DownloadManager.java +++ b/core/src/com/cloud/storage/template/DownloadManager.java @@ -44,7 +44,7 @@ public interface DownloadManager extends Manager { * @param resourceType signifying the type of resource like template, volume etc. * @return job-id that can be used to interrogate the status of the download. */ - public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType); + public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String templatePath, String userName, String passwd, long maxDownloadSizeInBytes, Proxy proxy, ResourceType resourceType); public String downloadS3Template(S3TO s3, long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType); diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 53810e9083c..7a69dab3704 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -16,15 +16,9 @@ // under the License. package com.cloud.storage.template; -import static com.cloud.utils.S3Utils.putDirectory; -import static com.cloud.utils.StringUtils.join; -import static java.lang.String.format; -import static java.util.Arrays.asList; - import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; @@ -51,14 +45,8 @@ import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; -import org.apache.commons.httpclient.Credentials; -import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; import org.apache.log4j.Logger; -import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.DataStoreTO; @@ -74,9 +62,6 @@ import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.TemplateDownloader.DownloadCompleteCallback; import com.cloud.storage.template.TemplateDownloader.Status; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.S3Utils; -import com.cloud.utils.UriUtils; -import com.cloud.utils.S3Utils.ObjectNamingStrategy; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.OutputInterpreter; @@ -348,9 +333,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private String postDownload(String jobId) { DownloadJob dnld = jobs.get(jobId); TemplateDownloader td = dnld.getTemplateDownloader(); - String resourcePath = null; + String resourcePath = dnld.getInstallPathPrefix(); // path with mount directory + String finalResourcePath = dnld.getTmpltPath(); // template download path on secondary storage ResourceType resourceType = dnld.getResourceType(); + /* // once template path is set, remove the parent dir so that the template // is installed with a relative path String finalResourcePath = ""; @@ -364,6 +351,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager _storage.mkdirs(resourcePath); dnld.setTmpltPath(finalResourcePath); + */ File originalTemplate = new File(td.getDownloadLocalPath()); String checkSum = computeCheckSum(originalTemplate); @@ -396,12 +384,13 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString(); } + // run script to mv the temporary template file to the final template file String templateFilename = templateName + "." + extension; dnld.setTmpltPath(finalResourcePath + "/" + templateFilename); scr.add("-n", templateFilename); scr.add("-t", resourcePath); - scr.add("-f", td.getDownloadLocalPath()); + scr.add("-f", td.getDownloadLocalPath()); // this is the temporary template file downloaded if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) { scr.add("-c", dnld.getChecksum()); } @@ -507,7 +496,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager @Override public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, - String cksum, String installPathPrefix, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + String cksum, String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); String tmpDir = installPathPrefix; @@ -555,7 +544,10 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } else { throw new CloudRuntimeException("Unable to download from URL: " + url); } + // NOTE the difference between installPathPrefix and templatePath here. instalPathPrefix is the absolute path for template including mount directory + // on ssvm, while templatePath is the final relative path on secondary storage. DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); + dj.setTmpltPath(templatePath); jobs.put(jobId, dj); threadPool.execute(td); @@ -686,7 +678,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } else { jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), - cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + cmd.getDescription(), cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } sleep(); if (jobId == null) { diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java index 56da8c0e7d1..e832c0291e5 100644 --- a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java +++ b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java @@ -166,8 +166,8 @@ public class HttpTemplateDownloader implements TemplateDownloader { throw new IllegalArgumentException("Unsupported scheme for url"); } int port = uri.getPort(); - if (!(port == 80 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); + if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { + throw new IllegalArgumentException("Only ports 80, 8080 and 443 are allowed"); } if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index 60dc16127fa..0a460466036 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -8,9 +8,12 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.HashMap; import java.util.List; import java.util.concurrent.Executors; +import javax.naming.ConfigurationException; + import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; import org.springframework.stereotype.Component; @@ -24,6 +27,7 @@ import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.storage.JavaStorageLayer; +import com.cloud.storage.StorageLayer; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.resource.NfsSecondaryStorageResource; import com.cloud.storage.template.DownloadManagerImpl; @@ -37,10 +41,21 @@ public class MockLocalNfsSecondaryStorageResource extends public MockLocalNfsSecondaryStorageResource(){ _dlMgr = new DownloadManagerImpl(); + _storage = new JavaStorageLayer(); + HashMap params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, _storage); + try { + _dlMgr.configure("downloadMgr", params); + } catch (ConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + /* _storage = new JavaStorageLayer(); ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); ((DownloadManagerImpl)_dlMgr).setStorageLayer(_storage); + */ } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 4d600785526..8bf14f60eac 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -37,6 +37,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String primaryStorageUrl; private String secondaryStorage; private String imageInstallPath; + private String scriptPath; private Transaction txn; private String s3AccessKey; @@ -71,11 +72,11 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path", "primary-storage-uuid-want-to-add"}) + "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path", "primary-storage-uuid-want-to-add", "script-path"}) protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid, String primaryStorage, String secondaryStorage, String s3_accessKey, String s3_secretKey, String s3_endpoint, String s3_template_bucket, - String s3_usehttps, String imageInstallPath, String primaryStorageUuid) { + String s3_usehttps, String imageInstallPath, String primaryStorageUuid, String scriptPath) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -92,6 +93,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.s3EndPoint = s3_endpoint; this.s3TemplateBucket = s3_template_bucket; this.s3UseHttps = Boolean.parseBoolean(s3_usehttps); + this.scriptPath = scriptPath; } protected String getHostGuid() { @@ -167,4 +169,13 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.primaryStorageUuid = primaryStorageUuid; } + public String getScriptPath() { + return scriptPath; + } + + public void setScriptPath(String scriptPath) { + this.scriptPath = scriptPath; + } + + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index a38b91c3252..3ef1b542743 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -68,6 +68,7 @@ public class TemplateTest extends CloudStackTestNGBase { @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); + System.setProperty("paths.script", this.getScriptPath()); //create data center DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); diff --git a/engine/storage/integration-test/test/resource/testng.xml b/engine/storage/integration-test/test/resource/testng.xml index 4b074487b4c..a6dc392caa7 100644 --- a/engine/storage/integration-test/test/resource/testng.xml +++ b/engine/storage/integration-test/test/resource/testng.xml @@ -23,12 +23,14 @@ - + + + diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 39d3ce20c16..828f34a71aa 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -2380,9 +2380,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } int port = uri.getPort(); - if (!(port == 80 || port == 443 || port == -1)) { + if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { throw new IllegalArgumentException( - "Only ports 80 and 443 are allowed"); + "Only ports 80, 8080 and 443 are allowed"); } String host = uri.getHost(); try { @@ -2468,21 +2468,21 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw new CloudRuntimeException("Failed to destroy volume" + volume.getId(), e); } } - - - - + + + + @Override public Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account) throws ResourceAllocationException { VolumeInfo volume = this.volFactory.getVolume(volumeId); if (volume == null) { throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist"); } - + if (volume.getState() != Volume.State.Ready) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot."); } - + CreateSnapshotPayload payload = new CreateSnapshotPayload(); payload.setSnapshotId(snapshotId); payload.setSnapshotPolicyId(policyId); @@ -2523,7 +2523,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (storagePool == null) { throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it"); } - + return this.snapshotMgr.allocSnapshot(volumeId, policyId); } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 35bc5e5d678..2e50406debb 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -86,8 +86,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { } int port = uri.getPort(); - if (!(port == 80 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); + if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { + throw new IllegalArgumentException("Only ports 80, 8080 and 443 are allowed"); } String host = uri.getHost(); try { diff --git a/utils/src/com/cloud/utils/UriUtils.java b/utils/src/com/cloud/utils/UriUtils.java index ef1aba24a00..2673177ad96 100644 --- a/utils/src/com/cloud/utils/UriUtils.java +++ b/utils/src/com/cloud/utils/UriUtils.java @@ -137,8 +137,8 @@ public class UriUtils { throw new IllegalArgumentException("Unsupported scheme for url"); } int port = uri.getPort(); - if (!(port == 80 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80 and 443 are allowed"); + if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { + throw new IllegalArgumentException("Only ports 80, 8080 and 443 are allowed"); } if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { From 66337e8e9cd92196b5f706bbce5abf93661c12b5 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Tue, 7 May 2013 14:24:39 -0700 Subject: [PATCH 123/303] Zone wizard: fix secondary storage dropdown event --- ui/scripts/zoneWizard.js | 94 ++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 03339fb8f99..91227936e90 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -1526,73 +1526,75 @@ data: items }); - args.$select.change(function() { + args.$select.change(function() { var $form = $(this).closest('form'); + var $fields = $form.find('.field'); + if($(this).val() == "NFS") { //NFS - $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); - $form.find('.form-item[rel=path]').css('display', 'inline-block'); + $fields.filter('[rel=zoneid]').css('display', 'inline-block'); + $fields.filter('[rel=nfsServer]').css('display', 'inline-block'); + $fields.filter('[rel=path]').css('display', 'inline-block'); //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); + $fields.filter('[rel=accesskey]').hide(); + $fields.filter('[rel=secretkey]').hide(); + $fields.filter('[rel=bucket]').hide(); + $fields.filter('[rel=endpoint]').hide(); + $fields.filter('[rel=usehttps]').hide(); + $fields.filter('[rel=connectiontimeout]').hide(); + $fields.filter('[rel=maxerrorretry]').hide(); + $fields.filter('[rel=sockettimeout]').hide(); //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); + $fields.filter('[rel=url]').hide(); + $fields.filter('[rel=account]').hide(); + $fields.filter('[rel=username]').hide(); + $fields.filter('[rel=key]').hide(); } else if ($(this).val() == "S3") { //NFS - $form.find('.form-item[rel=zoneid]').hide(); - $form.find('.form-item[rel=nfsServer]').hide(); - $form.find('.form-item[rel=path]').hide(); + $fields.filter('[rel=zoneid]').hide(); + $fields.filter('[rel=nfsServer]').hide(); + $fields.filter('[rel=path]').hide(); //S3 - $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); - $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); - $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); - $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); - $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); - $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); - $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); - $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + $fields.filter('[rel=accesskey]').css('display', 'inline-block'); + $fields.filter('[rel=secretkey]').css('display', 'inline-block'); + $fields.filter('[rel=bucket]').css('display', 'inline-block'); + $fields.filter('[rel=endpoint]').css('display', 'inline-block'); + $fields.filter('[rel=usehttps]').css('display', 'inline-block'); + $fields.filter('[rel=connectiontimeout]').css('display', 'inline-block'); + $fields.filter('[rel=maxerrorretry]').css('display', 'inline-block'); + $fields.filter('[rel=sockettimeout]').css('display', 'inline-block'); //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); + $fields.filter('[rel=url]').hide(); + $fields.filter('[rel=account]').hide(); + $fields.filter('[rel=username]').hide(); + $fields.filter('[rel=key]').hide(); } else if($(this).val() == "Swift") { //NFS - $form.find('.form-item[rel=zoneid]').hide(); - $form.find('.form-item[rel=nfsServer]').hide(); - $form.find('.form-item[rel=path]').hide(); + $fields.filter('[rel=zoneid]').hide(); + $fields.filter('[rel=nfsServer]').hide(); + $fields.filter('[rel=path]').hide(); //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); + $fields.filter('[rel=accesskey]').hide(); + $fields.filter('[rel=secretkey]').hide(); + $fields.filter('[rel=bucket]').hide(); + $fields.filter('[rel=endpoint]').hide(); + $fields.filter('[rel=usehttps]').hide(); + $fields.filter('[rel=connectiontimeout]').hide(); + $fields.filter('[rel=maxerrorretry]').hide(); + $fields.filter('[rel=sockettimeout]').hide(); //Swift - $form.find('.form-item[rel=url]').css('display', 'inline-block'); - $form.find('.form-item[rel=account]').css('display', 'inline-block'); - $form.find('.form-item[rel=username]').css('display', 'inline-block'); - $form.find('.form-item[rel=key]').css('display', 'inline-block'); + $fields.filter('[rel=url]').css('display', 'inline-block'); + $fields.filter('[rel=account]').css('display', 'inline-block'); + $fields.filter('[rel=username]').css('display', 'inline-block'); + $fields.filter('[rel=key]').css('display', 'inline-block'); } }); From bc97dbde526e1b7eadc57148f3d26cfe7f422033 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 16:40:21 -0700 Subject: [PATCH 124/303] Fix a bug in ListImageStoresCmd when id is passed. --- .../api/command/admin/storage/ListImageStoresCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java index fb589af8e14..57259b558a4 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/ListImageStoresCmd.java @@ -53,7 +53,7 @@ public class ListImageStoresCmd extends BaseListCmd { description="the Zone ID for the image store") private Long zoneId; - @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = StoragePoolResponse.class, + @Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType = ImageStoreResponse.class, description="the ID of the storage pool") private Long id; From e8c69632b6cbc6656b5c9296cbd3cf3dc8b14339 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 16:44:05 -0700 Subject: [PATCH 125/303] Fix an issue in showing removed templates in list call. --- server/src/com/cloud/api/query/QueryManagerImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index a79a2b296ce..807f2d64f1b 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2681,6 +2681,9 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); } + // don't return removed template + sc.addAnd("removed", SearchCriteria.Op.NULL); + // search unique templates and find details by Ids Pair, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); Integer count = uniqueTmplPair.second(); From 70f866156ffda99d5e769219bfaa46734842fcd7 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 16:45:37 -0700 Subject: [PATCH 126/303] Fix a bug in updating template_store_ref entry. --- .../CloudStackImageStoreDriverImpl.java | 25 +++++++++++-------- .../driver/S3ImageStoreDriverImpl.java | 25 +++++++++++-------- .../driver/SwiftImageStoreDriverImpl.java | 25 +++++++++++-------- 3 files changed, 42 insertions(+), 33 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index c30d8a6bbc4..45c6b8ba36d 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -175,17 +175,20 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { DataObject obj = context.data; DataStore store = obj.getDataStore(); - TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _templateStoreDao.update(store.getId(), updateBuilder); + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(),obj.getId()); + if (tmpltStoreVO != null) { + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + } AsyncCompletionCallback caller = context.getParentCallback(); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index b64f934d625..acff2be0b0b 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -225,17 +225,20 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { DataObject obj = context.data; DataStore store = obj.getDataStore(); - TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _templateStoreDao.update(store.getId(), updateBuilder); + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(),obj.getId()); + if (tmpltStoreVO != null) { + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + } AsyncCompletionCallback caller = context.getParentCallback(); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 8446eeb2b5f..a8fb3b2f058 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -178,17 +178,20 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { DataObject obj = context.data; DataStore store = obj.getDataStore(); - TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _templateStoreDao.update(store.getId(), updateBuilder); + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(),obj.getId()); + if (tmpltStoreVO != null) { + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + } AsyncCompletionCallback caller = context.getParentCallback(); From 8984e430cebb36a93494e7ebc5a51420b48ddc6b Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 16:46:26 -0700 Subject: [PATCH 127/303] Add state transition for destroy scenario. --- .../storage/image/TemplateServiceImpl.java | 26 ++++++++++++++++--- .../ObjectInDataStoreManagerImpl.java | 10 +++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index c7eb069f575..3fee59c06e8 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -154,9 +154,21 @@ public class TemplateServiceImpl implements TemplateService { public void createTemplateAsync( TemplateInfo template, DataStore store, AsyncCompletionCallback callback) { // persist template_store_ref entry - DataObject templateOnStore = store.create(template); - // update template_store_ref state - templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); + TemplateObject templateOnStore = (TemplateObject)store.create(template); + // update template_store_ref and template state + try { + templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); + templateOnStore.stateTransit(TemplateEvent.CreateRequested); + } catch (NoTransitionException e) { + s_logger.debug("Failed to transit state", e); + TemplateApiResult result = new TemplateApiResult(templateOnStore); + result.setResult(e.toString()); + result.setSucess(false); + if ( callback != null ){ + callback.complete(result); + } + return; + } TemplateOpContext context = new TemplateOpContext(callback, (TemplateObject)templateOnStore, null); @@ -482,6 +494,14 @@ public class TemplateServiceImpl implements TemplateService { TemplateObject to = (TemplateObject) template; // update template_store_ref status to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + try { + to.stateTransit(TemplateEvent.DestroyRequested); + } catch (NoTransitionException e) { + s_logger.debug("Failed to transit state", e); + //TODO: not fatal right now, still continue + } + + AsyncCallFuture future = new AsyncCallFuture(); TemplateOpContext context = new TemplateOpContext(null, to, future); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 763d2cabf7c..82d29f1a04d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -24,6 +24,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -98,6 +100,14 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { State.Ready); stateMachines.addTransition(State.Copying, Event.OperationFailed, State.Ready); + stateMachines.addTransition(State.Ready, Event.DestroyRequested, + State.Destroying); + stateMachines.addTransition(State.Destroying, Event.DestroyRequested, + State.Destroying); + stateMachines.addTransition(State.Destroying, Event.OperationSuccessed, + State.Destroyed); + stateMachines.addTransition(State.Destroying, Event.OperationFailed, + State.Destroying); } @Override From d79b890904347c4ded0f5713e22776e974164e8c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 17:42:52 -0700 Subject: [PATCH 128/303] Change VMTemplate state in destroy. --- .../cloudstack/storage/image/TemplateServiceImpl.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 3fee59c06e8..b19fc65dbe0 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -511,8 +511,8 @@ public class TemplateServiceImpl implements TemplateService { return future; } - public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, TemplateOpContext context) { - TemplateApiResult result = callback.getResult(); + public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, TemplateOpContext context) { + CommandResult result = callback.getResult(); TemplateObject vo = context.getTemplate(); // we can only update state in template_store_ref table if (result.isSuccess()) { @@ -520,7 +520,10 @@ public class TemplateServiceImpl implements TemplateService { } else { vo.processEvent(Event.OperationFailed); } - context.future.complete(result); + TemplateApiResult apiResult = new TemplateApiResult(vo); + apiResult.setResult(result.getResult()); + apiResult.setSucess(result.isSuccess()); + context.future.complete(apiResult); return null; } From 8a514ea4b885907502a3c98557343df06b3a982c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 17:44:46 -0700 Subject: [PATCH 129/303] Update template size in VMTemplate table. --- .../datastore/driver/CloudStackImageStoreDriverImpl.java | 4 ++++ .../storage/datastore/driver/S3ImageStoreDriverImpl.java | 4 ++++ .../storage/datastore/driver/SwiftImageStoreDriverImpl.java | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 45c6b8ba36d..8e9572cf039 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -188,6 +188,10 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + // update size in vm_template table + VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); + tmlptUpdater.setSize(answer.getTemplateSize()); + templateDao.update(obj.getId(), tmlptUpdater); } AsyncCompletionCallback caller = context.getParentCallback(); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index acff2be0b0b..b1d2f952c13 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -238,6 +238,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + // update size in vm_template table + VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); + tmlptUpdater.setSize(answer.getTemplateSize()); + templateDao.update(obj.getId(), tmlptUpdater); } AsyncCompletionCallback caller = context.getParentCallback(); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index a8fb3b2f058..bbda45cc7d1 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -191,6 +191,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { updateBuilder.setSize(answer.getTemplateSize()); updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + // update size in vm_template table + VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); + tmlptUpdater.setSize(answer.getTemplateSize()); + templateDao.update(obj.getId(), tmlptUpdater); } AsyncCompletionCallback caller = context.getParentCallback(); From ac1b75dc9f212ba97f1acf6759151cd8d3f0ff10 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 7 May 2013 17:58:45 -0700 Subject: [PATCH 130/303] Fix a bug in deleteTemplate return result. --- .../datastore/driver/CloudStackImageStoreDriverImpl.java | 2 +- .../storage/datastore/driver/S3ImageStoreDriverImpl.java | 2 +- .../storage/datastore/driver/SwiftImageStoreDriverImpl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 8e9572cf039..84c5ea53994 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -299,7 +299,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } else { s_logger.debug("Deleted template at: " + installPath); CommandResult result = new CommandResult(); - result.setSucess(false); + result.setSucess(true); callback.complete(result); } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index b1d2f952c13..354151eaa3c 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -311,7 +311,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } else { s_logger.debug("Deleted template at: " + installPath); CommandResult result = new CommandResult(); - result.setSucess(false); + result.setSucess(true); callback.complete(result); } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index bbda45cc7d1..0eb3acfc6a3 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -302,7 +302,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } else { s_logger.debug("Deleted template at: " + installPath); CommandResult result = new CommandResult(); - result.setSucess(false); + result.setSucess(true); callback.complete(result); } From 5aeca646ae18f620ea41ecbd8c1128aa1d1f30b2 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 7 May 2013 17:46:10 -0700 Subject: [PATCH 131/303] make create template from volume/snapshot work --- .../resource/NfsSecondaryStorageResource.java | 118 +++++++++++++++--- .../storage/to/SnapshotObjectTO.java | 11 ++ .../motion/AncientDataMotionStrategy.java | 2 +- .../storage/test/CloudStackTestNGBase.java | 3 + .../cloudstack/storage/test/SnapshotTest.java | 62 +++++++-- .../cloudstack/storage/test/TemplateTest.java | 2 +- .../cloudstack/storage/test/VolumeTest.java | 51 ++++++++ .../endpoint/DefaultEndPointSelector.java | 19 ++- .../resource/XenServerStorageResource.java | 82 +++++++++++- ...reate_privatetemplate_from_snapshot_xen.sh | 98 +++++++++++++++ 10 files changed, 407 insertions(+), 41 deletions(-) create mode 100755 scripts/storage/secondary/create_privatetemplate_from_snapshot_xen.sh diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 48854dfbcb5..e9ec8391910 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -53,6 +53,7 @@ import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -103,6 +104,7 @@ import com.cloud.agent.api.to.SwiftTO; import com.cloud.exception.InternalErrorException; import com.cloud.host.Host; import com.cloud.host.Host.Type; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ServerResourceBase; import com.cloud.storage.DataStoreRole; import com.cloud.storage.StorageLayer; @@ -110,10 +112,14 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.template.DownloadManager; import com.cloud.storage.template.DownloadManagerImpl; import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.UploadManager; import com.cloud.storage.template.UploadManagerImpl; +import com.cloud.storage.template.VhdProcessor; import com.cloud.utils.NumbersUtil; import com.cloud.utils.S3Utils; import com.cloud.utils.S3Utils.FileNamingStrategy; @@ -161,6 +167,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S final private String _parent = "/mnt/SecStorage"; final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; + private String createTemplateFromSnapshotXenScript; @Override public void disconnected() { @@ -280,11 +287,90 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new CopyCmdAnswer(errMsg); } } + + + protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { + String srcMountPoint = this.getRootDir(srcDataStore.getUrl()); + String snapshotPath = srcData.getPath(); + int index = snapshotPath.lastIndexOf("/"); + String snapshotName = snapshotPath.substring(index + 1); + if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) { + snapshotName = snapshotName + ".vhd"; + } + snapshotPath = snapshotPath.substring(0, index); + snapshotPath = srcMountPoint + snapshotPath; + String destMountPoint = this.getRootDir(destDataStore.getUrl()); + String destPath = destMountPoint + destData.getPath(); - protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, + String errMsg = null; + try { + this._storage.mkdir(destPath); - DataTO destData, NfsTO destImageStore) { - return Answer.createUnsupportedCommandAnswer(cmd); + String templateUuid = UUID.randomUUID().toString(); + String templateName = templateUuid + ".vhd"; + Script command = new Script(this.createTemplateFromSnapshotXenScript, cmd.getWait(), s_logger); + command.add("-p", snapshotPath); + command.add("-s", snapshotName); + command.add("-n", templateName); + command.add("-t", destPath); + command.execute(); + + Map params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, _storage); + Processor processor = new VhdProcessor(); + + processor.configure("Vhd Processor", params); + FormatInfo info = processor.process(destPath, null, + templateUuid); + + TemplateLocation loc = new TemplateLocation(_storage, destPath); + loc.create(1, true, templateName); + loc.addFormat(info); + loc.save(); + + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(destData.getPath() + File.separator + templateUuid); + return new CopyCmdAnswer(newTemplate); + } catch (ConfigurationException e) { + s_logger.debug("Failed to create template from snapshot: " + e.toString()); + errMsg = e.toString(); + } catch (InternalErrorException e) { + s_logger.debug("Failed to create template from snapshot: " + e.toString()); + errMsg = e.toString(); + } catch (IOException e) { + s_logger.debug("Failed to create template from snapshot: " + e.toString()); + errMsg = e.toString(); + } + + return new CopyCmdAnswer(errMsg); + } + + protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { + + if (srcData.getHypervisorType() == HypervisorType.XenServer) { + return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore); + } + + return new CopyCmdAnswer(""); + } + + protected Answer createTemplateFromSnapshot(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + DataStoreTO srcDataStore = srcData.getDataStore(); + DataStoreTO destDataStore = destData.getDataStore(); + if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache) { + if (!(srcDataStore instanceof NfsTO)) { + s_logger.debug("only support nfs storage as src, when create template from snapshot"); + return Answer.createUnsupportedCommandAnswer(cmd); + } + + if (destDataStore instanceof NfsTO){ + return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore); + } + + } + return new CopyCmdAnswer(""); } protected Answer execute(CopyCommand cmd) { @@ -292,23 +378,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore(); - - if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache) { - - if (!(destDataStore instanceof NfsTO)) { - s_logger.debug("only support nfs as cache storage"); - return Answer.createUnsupportedCommandAnswer(cmd); - } - - if (srcDataStore instanceof S3TO) { - return copyFromS3ToNfs(cmd, srcData, (S3TO) srcDataStore, destData, (NfsTO) destDataStore); - } else if (srcDataStore instanceof SwiftTO) { - return copyFromSwiftToNfs(cmd, srcData, (SwiftTO) srcDataStore, destData, (NfsTO) destDataStore); - } else { - return Answer.createUnsupportedCommandAnswer(cmd); - } - + + if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) { + return createTemplateFromSnapshot(cmd); } + + return Answer.createUnsupportedCommandAnswer(cmd); } @@ -1652,6 +1727,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (_configIpFirewallScr != null) { s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr); } + + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh"); + if (createTemplateFromSnapshotXenScript == null) { + throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir()); + } _role = (String) params.get("role"); if (_role == null) diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java index 6d98045cc7a..ed4cbe1756a 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -5,6 +5,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.hypervisor.Hypervisor.HypervisorType; public class SnapshotObjectTO implements DataTO { private String path; @@ -13,6 +14,7 @@ public class SnapshotObjectTO implements DataTO { private DataStoreTO dataStore; private String vmName; private String name; + private HypervisorType hypervisorType; private long id; public SnapshotObjectTO() { @@ -29,6 +31,7 @@ public class SnapshotObjectTO implements DataTO { } this.dataStore = snapshot.getDataStore().getTO(); this.setName(snapshot.getName()); + this.hypervisorType = snapshot.getHypervisorType(); } @Override @@ -89,4 +92,12 @@ public class SnapshotObjectTO implements DataTO { public void setName(String name) { this.name = name; } + + public HypervisorType getHypervisorType() { + return hypervisorType; + } + + public void setHypervisorType(HypervisorType hypervisorType) { + this.hypervisorType = hypervisorType; + } } 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 index db3971c673e..560c34f0a3f 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -327,7 +327,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { .parseInt(Config.CreatePrivateTemplateFromSnapshotWait .getDefaultValue())); - if (srcData.getDataStore().getRole() != DataStoreRole.ImageCache && destData.getDataStore().getRole() != DataStoreRole.ImageCache) { + if (needCacheStorage(srcData, destData)) { SnapshotInfo snapshot = (SnapshotInfo)srcData; srcData = cacheSnapshotChain(snapshot); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 8bf14f60eac..77b6ec302cc 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -94,6 +94,9 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.s3TemplateBucket = s3_template_bucket; this.s3UseHttps = Boolean.parseBoolean(s3_usehttps); this.scriptPath = scriptPath; + if (this.scriptPath != null) { + System.setProperty("paths.script", this.getScriptPath()); + } } protected String getHostGuid() { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 203f762a0e4..9dc68546005 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -29,6 +29,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -45,6 +46,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource; import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; @@ -144,6 +147,7 @@ public class SnapshotTest extends CloudStackTestNGBase { SnapshotDao snapshotDao; @Inject EndPointSelector epSelector; + long primaryStoreId; VMTemplateVO image; String imageStoreName = "testImageStore"; @@ -196,7 +200,7 @@ public class SnapshotTest extends CloudStackTestNGBase { imageStore = new ImageStoreVO(); imageStore.setName(imageStoreName); imageStore.setDataCenterId(dcId); - imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setProviderName(DataStoreProvider.NFS_IMAGE); imageStore.setRole(DataStoreRole.Image); imageStore.setUrl(this.getSecondaryStorage()); imageStore.setUuid(UUID.randomUUID().toString()); @@ -301,7 +305,7 @@ public class SnapshotTest extends CloudStackTestNGBase { pool.setPoolType(StoragePoolType.NetworkFilesystem); pool.setPodId(podId); pool.setScope(ScopeType.CLUSTER); - pool.setStorageProviderName("cloudstack primary data store provider"); + pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY); pool = this.primaryStoreDao.persist(pool); DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); return store; @@ -359,15 +363,49 @@ public class SnapshotTest extends CloudStackTestNGBase { } } } - - //@Test - public void testCreateDataDisk() { - DataStore primaryStore = createPrimaryDataStore(); - primaryStoreId = primaryStore.getId(); - primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); - VolumeVO volume = createVolume(null, primaryStore.getId()); - VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - this.volumeService.createVolumeAsync(volInfo, primaryStore); + + private VMTemplateVO createTemplateInDb() { + image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + image = imageDataDao.persist(image); + return image; + } + + @Test + public void createTemplateFromSnapshot() { + VolumeInfo vol = createCopyBaseImage(); + SnapshotVO snapshotVO = createSnapshotInDb(vol); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + boolean result = false; + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + snapshot = strategy.takeSnapshot(snapshot); + result = true; + } + } + + AssertJUnit.assertTrue(result); + LocalHostEndpoint ep = new LocalHostEndpoint(); + ep.setResource(new MockLocalNfsSecondaryStorageResource()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); + VMTemplateVO templateVO = createTemplateInDb(); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId()); + DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); + this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); } - } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index 3ef1b542743..294d4b5a2c2 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -68,7 +68,7 @@ public class TemplateTest extends CloudStackTestNGBase { @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); - System.setProperty("paths.script", this.getScriptPath()); + //create data center DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index 01715451f33..a35495999d4 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -379,4 +379,55 @@ public class VolumeTest extends CloudStackTestNGBase { } } + + private VMTemplateVO createTemplateInDb() { + image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + image = imageDataDao.persist(image); + return image; + } + + @Test + public void testCreateTemplateFromVolume() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); + try { + VolumeApiResult result = future.get(); + + AssertJUnit.assertTrue(result.isSuccess()); + volInfo = result.getVolume(); + VMTemplateVO templateVO = createTemplateInDb(); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId()); + DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); + + this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 5b223010d9b..54059f28a59 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -83,6 +83,16 @@ public class DefaultEndPointSelector implements EndPointSelector { return false; } } + + protected boolean moveBetweenImages(DataStore srcStore, DataStore destStore) { + DataStoreRole srcRole = srcStore.getRole(); + DataStoreRole destRole = destStore.getRole(); + if (srcRole == DataStoreRole.Image && destRole == DataStoreRole.Image) { + return true; + } else { + return false; + } + } @DB protected EndPoint findEndPointInScope(Scope scope, String sqlBase) { @@ -162,12 +172,11 @@ public class DefaultEndPointSelector implements EndPointSelector { if (moveBetweenPrimaryImage(srcStore, destStore)) { return findEndPointForImageMove(srcStore, destStore); } else if (moveBetweenCacheAndImage(srcStore, destStore)) { - EndPoint ep = findEndPointForImageMove(srcStore, destStore); - if (ep == null) { - //if there is no ssvm agent running, use mgt server - ep = new LocalHostEndpoint(); - } + EndPoint ep = findEndpointForImageStorage(destStore); return ep; + } else if (moveBetweenImages(srcStore, destStore)) { + EndPoint ep = findEndpointForImageStorage(destStore); + return ep; } // TODO Auto-generated method stub return null; diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index ab01c7262e8..fc3a0dde3a6 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -70,6 +70,7 @@ import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CreateAnswer; +import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; @@ -81,6 +82,7 @@ import com.cloud.agent.api.to.VolumeTO; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.S3Utils; import com.cloud.utils.StringUtils; import com.cloud.utils.exception.CloudRuntimeException; @@ -1200,7 +1202,7 @@ public class XenServerStorageResource { destroySnapshotOnPrimaryStorageExceptThis(conn, volumeUuid, snapshotUuid); SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(snapshotBackupUuid); + newSnapshot.setPath(folder + File.separator + snapshotBackupUuid); if (fullbackup) { newSnapshot.setParentSnapshotPath(null); } else { @@ -1217,6 +1219,76 @@ public class XenServerStorageResource { return new CopyCmdAnswer(details); } + + protected CopyCmdAnswer createTemplateFromVolume(DataTO srcData, DataTO destData, int wait) { + Connection conn = this.hypervisorResource.getConnection(); + VolumeObjectTO volume = (VolumeObjectTO)srcData; + TemplateObjectTO template = (TemplateObjectTO)destData; + NfsTO destStore = (NfsTO)destData.getDataStore(); + + String secondaryStoragePoolURL = destStore.getUrl(); + String volumeUUID = volume.getPath(); + + String userSpecifiedName = template.getName(); + + + String details = null; + SR tmpltSR = null; + boolean result = false; + String secondaryStorageMountPath = null; + String installPath = null; + try { + URI uri = new URI(secondaryStoragePoolURL); + secondaryStorageMountPath = uri.getHost() + ":" + uri.getPath(); + installPath = template.getPath(); + if( !this.hypervisorResource.createSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath)) { + details = " Filed to create folder " + installPath + " in secondary storage"; + s_logger.warn(details); + return new CopyCmdAnswer(details); + } + + VDI vol = getVDIbyUuid(conn, volumeUUID); + // create template SR + URI tmpltURI = new URI(secondaryStoragePoolURL + "/" + installPath); + tmpltSR = this.hypervisorResource.createNfsSRbyURI(conn, tmpltURI, false); + + // copy volume to template SR + VDI tmpltVDI = this.hypervisorResource.cloudVDIcopy(conn, vol, tmpltSR, wait); + // scan makes XenServer pick up VDI physicalSize + tmpltSR.scan(conn); + if (userSpecifiedName != null) { + tmpltVDI.setNameLabel(conn, userSpecifiedName); + } + + String tmpltUUID = tmpltVDI.getUuid(conn); + String tmpltFilename = tmpltUUID + ".vhd"; + long virtualSize = tmpltVDI.getVirtualSize(conn); + long physicalSize = tmpltVDI.getPhysicalUtilisation(conn); + // create the template.properties file + String templatePath = secondaryStorageMountPath + "/" + installPath; + result = this.hypervisorResource.postCreatePrivateTemplate(conn, templatePath, tmpltFilename, tmpltUUID, userSpecifiedName, null, physicalSize, virtualSize, template.getId()); + if (!result) { + throw new CloudRuntimeException("Could not create the template.properties file on secondary storage dir: " + tmpltURI); + } + installPath = installPath + "/" + tmpltFilename; + this.hypervisorResource.removeSR(conn, tmpltSR); + tmpltSR = null; + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(installPath); + CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); + return answer; + } catch (Exception e) { + if (tmpltSR != null) { + this.hypervisorResource.removeSR(conn, tmpltSR); + } + if ( secondaryStorageMountPath != null) { + this.hypervisorResource.deleteSecondaryStorageFolder(conn, secondaryStorageMountPath, installPath); + } + details = "Creating template from volume " + volumeUUID + " failed due to " + e.toString(); + s_logger.error(details, e); + } + return new CopyCmdAnswer(details); + } protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); @@ -1235,11 +1307,15 @@ public class XenServerStorageResource { } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { //clone template to a volume return cloneVolumeFromBaseTemplate(srcData, destData); - } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.ImageCache) { + } else if (srcData.getObjectType() == DataObjectType.VOLUME && (srcData.getDataStore().getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Image)) { //copy volume from image cache to primary return copyVolumeFromImageCacheToPrimary(srcData, destData, cmd.getWait()); } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { - return copyVolumeFromPrimaryToSecondary(srcData, destData, cmd.getWait()); + if (destData.getObjectType() == DataObjectType.VOLUME) { + return copyVolumeFromPrimaryToSecondary(srcData, destData, cmd.getWait()); + } else if (destData.getObjectType() == DataObjectType.TEMPLATE) { + return createTemplateFromVolume(srcData, destData, cmd.getWait()); + } } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) { DataTO cacheData = cmd.getCacheTO(); return backupSnasphot(srcData, destData, cacheData, cmd.getWait()); diff --git a/scripts/storage/secondary/create_privatetemplate_from_snapshot_xen.sh b/scripts/storage/secondary/create_privatetemplate_from_snapshot_xen.sh new file mode 100755 index 00000000000..309bcbdb683 --- /dev/null +++ b/scripts/storage/secondary/create_privatetemplate_from_snapshot_xen.sh @@ -0,0 +1,98 @@ +#!/bin/bash +# 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. + +#set -x + +usage() { + printf "Usage: %s -t [template path] -n [template name] -s [snapshot name] -p [snapshot path] \n" $(basename $0) +} + +snapshotPath= +snapshotName= +templatePath= +templateName= +while getopts ':s:n:t:p:' OPTION +do + case $OPTION in + t) tflag=1 + templatePath="$OPTARG" + ;; + n) nflag=1 + templateName="$OPTARG" + ;; + s) sflag=1 + snapshotName="$OPTARG" + ;; + p) pflag=1 + snapshotPath="$OPTARG" + ;; + ?) usage + exit 2 + ;; + esac +done + +if [ "$sflag$nflag$tflag$pflag" != "1111" ] +then + usage + exit 1 +fi + +VHDUTIL="/bin/vhd-util" +desvhd=$templatePath/$templateName +srcvhd=$snapshotPath/$snapshotName + +copyvhd() +{ + local desvhd=$1 + local srcvhd=$2 + local parent= + parent=`$VHDUTIL query -p -n $srcvhd` + if [ $? -ne 0 ]; then + echo "30#failed to query $srcvhd" + exit 2 + fi + if [[ "${parent}" =~ " no parent" ]]; then + dd if=$srcvhd of=$desvhd bs=2M + if [ $? -ne 0 ]; then + echo "31#failed to dd $srcvhd to $desvhd" + rm -rf $desvhd > /dev/null + exit 0 + fi + else + copyvhd $desvhd $parent + $VHDUTIL coalesce -p $desvhd -n $srcvhd + if [ $? -ne 0 ]; then + echo "32#failed to coalesce $desvhd to $srcvhd" + rm -rf $desvhd > /dev/null + exit 0 + fi + fi +} + +copyvhd $desvhd $srcvhd +imgsize=$(ls -l $desvhd| awk -F" " '{print $5}') +propertyFile=/$templatePath/template.properties +touch $propertyFile +echo -n "" > $propertyFile + +echo "filename=$templateName" > $propertyFile +echo "hvm=$hvm" >> $propertyFile +echo "size=$imgsize" >> $propertyFile + +exit 0 From ac7be218d55778e3e22d608b33dec4e0eea457c6 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 7 May 2013 20:15:35 -0700 Subject: [PATCH 132/303] creat template from volume/snapshot, and then create vm from template works now --- .../resource/NfsSecondaryStorageResource.java | 8 +++-- .../storage/image/TemplateServiceImpl.java | 4 +-- .../storage/image/store/TemplateObject.java | 35 +++++++++++++++++++ .../resource/XenServerStorageResource.java | 1 + .../cloud/template/TemplateManagerImpl.java | 19 ++++++++-- 5 files changed, 59 insertions(+), 8 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index e9ec8391910..384a41af4a0 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -107,6 +107,7 @@ import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.resource.ServerResourceBase; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageLayer; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.template.DownloadManager; @@ -298,9 +299,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S snapshotName = snapshotName + ".vhd"; } snapshotPath = snapshotPath.substring(0, index); - snapshotPath = srcMountPoint + snapshotPath; + snapshotPath = srcMountPoint + File.separator + snapshotPath; String destMountPoint = this.getRootDir(destDataStore.getUrl()); - String destPath = destMountPoint + destData.getPath(); + String destPath = destMountPoint + File.separator + destData.getPath(); String errMsg = null; try { @@ -329,7 +330,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S loc.save(); TemplateObjectTO newTemplate = new TemplateObjectTO(); - newTemplate.setPath(destData.getPath() + File.separator + templateUuid); + newTemplate.setPath(destData.getPath() + File.separator + templateName); + newTemplate.setFormat(ImageFormat.VHD); return new CopyCmdAnswer(newTemplate); } catch (ConfigurationException e) { s_logger.debug("Failed to create template from snapshot: " + e.toString()); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index b19fc65dbe0..95c6b399ff6 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -396,7 +396,7 @@ public class TemplateServiceImpl implements TemplateService { if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { //TODO: we cannot directly call deleteTemplateSync here to reuse delete logic since in this case, our db does not have this template at all. VMTemplateVO template = _templateDao.findById(tInfo.getId()); - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), template.getId(), template.getAccountId()); + DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), null, null); EndPoint ep = _epSelector.select(store); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { @@ -574,7 +574,7 @@ public class TemplateServiceImpl implements TemplateService { // remove entry from template_store_ref destTemplate.getDataStore().delete(destTemplate); } else { - destTemplate.processEvent(Event.OperationSuccessed); + destTemplate.processEvent(Event.OperationSuccessed, result.getAnswer()); } future.complete(res); } catch (Exception e) { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 7ff0cc324b2..37317b0ac4b 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -163,6 +163,7 @@ public class TemplateObject implements TemplateInfo { } public boolean stateTransit(TemplateEvent e) throws NoTransitionException { + this.imageVO = imageDao.findById(this.imageVO.getId()); boolean result= imageMgr.getStateMachine().transitTo(this.imageVO, e, null, imageDao); this.imageVO = imageDao.findById(this.imageVO.getId()); @@ -172,6 +173,22 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(Event event) { try { + if (this.getDataStore().getRole() == DataStoreRole.Image || + this.getDataStore().getRole() == DataStoreRole.ImageCache) { + TemplateEvent templEvent = null; + if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { + templEvent = TemplateEvent.CreateRequested; + } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { + templEvent = TemplateEvent.OperationSucceeded; + } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + templEvent = TemplateEvent.OperationFailed; + } + + if (templEvent != null) { + this.stateTransit(templEvent); + } + } + ojbectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); @@ -201,7 +218,25 @@ public class TemplateObject implements TemplateInfo { TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(), this.getId()); templateStoreRef.setInstallPath(newTemplate.getPath()); + templateStoreRef.setDownloadPercent(100); + templateStoreRef.setDownloadState(Status.DOWNLOADED); templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); + VMTemplateVO templateVO = this.imageDao.findById(this.getId()); + templateVO.setFormat(newTemplate.getFormat()); + this.imageDao.update(templateVO.getId(), templateVO); + } + + TemplateEvent templEvent = null; + if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { + templEvent = TemplateEvent.CreateRequested; + } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { + templEvent = TemplateEvent.OperationSucceeded; + } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + templEvent = TemplateEvent.OperationFailed; + } + + if (templEvent != null) { + this.stateTransit(templEvent); } } ojbectInStoreMgr.update(this, event); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java index fc3a0dde3a6..8b27efec8c0 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java @@ -1275,6 +1275,7 @@ public class XenServerStorageResource { tmpltSR = null; TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(installPath); + newTemplate.setFormat(ImageFormat.VHD); CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); return answer; } catch (Exception e) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 09cce637015..46c4c0a8605 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -22,6 +22,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.UUID; @@ -127,6 +128,7 @@ import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.TemplateProfile; import com.cloud.storage.Upload; import com.cloud.storage.Upload.Type; +import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateHostVO; @@ -1347,8 +1349,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, try { TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId); - snapshot = _snapshotDao.findById(snapshotId); - ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); + Long zoneId = null; + if (snapshotId != null) { + snapshot = _snapshotDao.findById(snapshotId); + zoneId = snapshot.getDataCenterId(); + + } else if (volumeId != null) { + volume = _volumeDao.findById(volumeId); + zoneId = volume.getDataCenterId(); + } + ZoneScope scope = new ZoneScope(zoneId); List store = this._dataStoreMgr.getImageStoresByScope(scope); if (store.size() > 1) { throw new CloudRuntimeException("muliple image data store, don't know which one to use"); @@ -1374,12 +1384,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.debug("Failed to create template" + result.getResult()); throw new CloudRuntimeException("Failed to create template" + result.getResult()); } + + VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date()); + this._tmpltZoneDao.persist(templateZone); privateTemplate = this._tmpltDao.findById(templateId); UsageEventVO usageEvent = new UsageEventVO( EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), - snapshot.getDataCenterId(), + zoneId, privateTemplate.getId(), privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), privateTemplate.getSize()); From f8edb554971268e25a5f752c4c1bef050c39b5ab Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 8 May 2013 10:29:09 -0700 Subject: [PATCH 133/303] Register template, delete template and create instance from registered template are working on NFS. --- .../storage/image/TemplateServiceImpl.java | 25 +++---------------- .../image/manager/ImageDataManagerImpl.java | 8 +++--- .../storage/image/store/TemplateObject.java | 14 +++++++---- .../ObjectInDataStoreManagerImpl.java | 3 +++ 4 files changed, 21 insertions(+), 29 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 95c6b399ff6..b8e81848a5e 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -156,11 +156,9 @@ public class TemplateServiceImpl implements TemplateService { // persist template_store_ref entry TemplateObject templateOnStore = (TemplateObject)store.create(template); // update template_store_ref and template state - try { + try{ templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); - templateOnStore.stateTransit(TemplateEvent.CreateRequested); - } catch (NoTransitionException e) { - s_logger.debug("Failed to transit state", e); + } catch (Exception e) { TemplateApiResult result = new TemplateApiResult(templateOnStore); result.setResult(e.toString()); result.setSucess(false); @@ -463,12 +461,7 @@ public class TemplateServiceImpl implements TemplateService { TemplateApiResult result = new TemplateApiResult(template); CreateCmdResult callbackResult = callback.getResult(); if (callbackResult.isFailed()) { - try { - template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); - template.stateTransit(TemplateEvent.OperationFailed); - } catch (NoTransitionException e) { - s_logger.debug("Failed to update template state", e); - } + template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); result.setResult(callbackResult.getResult()); parentCallback.complete(result); return null; @@ -476,9 +469,7 @@ public class TemplateServiceImpl implements TemplateService { try { template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); - template.stateTransit(TemplateEvent.OperationSucceeded); - } catch (NoTransitionException e) { - s_logger.debug("Failed to transit state", e); + } catch (Exception e) { result.setResult(e.toString()); parentCallback.complete(result); return null; @@ -494,13 +485,6 @@ public class TemplateServiceImpl implements TemplateService { TemplateObject to = (TemplateObject) template; // update template_store_ref status to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); - try { - to.stateTransit(TemplateEvent.DestroyRequested); - } catch (NoTransitionException e) { - s_logger.debug("Failed to transit state", e); - //TODO: not fatal right now, still continue - } - AsyncCallFuture future = new AsyncCallFuture(); @@ -514,7 +498,6 @@ public class TemplateServiceImpl implements TemplateService { public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, TemplateOpContext context) { CommandResult result = callback.getResult(); TemplateObject vo = context.getTemplate(); - // we can only update state in template_store_ref table if (result.isSuccess()) { vo.processEvent(Event.OperationSuccessed); } else { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java index 83e98878158..d8708308cef 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java @@ -27,9 +27,9 @@ import com.cloud.utils.fsm.StateMachine2; @Component public class ImageDataManagerImpl implements ImageDataManager { - private final StateMachine2 + private final StateMachine2 stateMachine = new StateMachine2(); - + public ImageDataManagerImpl() { stateMachine.addTransition(TemplateState.Allocated, TemplateEvent.CreateRequested, TemplateState.Creating); stateMachine.addTransition(TemplateState.Creating, TemplateEvent.CreateRequested, TemplateState.Creating); @@ -41,8 +41,10 @@ public class ImageDataManagerImpl implements ImageDataManager { stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.DestroyRequested, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationFailed, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationSucceeded, TemplateState.Destroyed); + //TODO: this should not be needed, but it happened during testing where multiple success event is sent to callback + stateMachine.addTransition(TemplateState.Ready, TemplateEvent.OperationSucceeded, TemplateState.Ready); } - + @Override public StateMachine2 getStateMachine() { return stateMachine; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 37317b0ac4b..61a81255a3d 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -178,17 +178,19 @@ public class TemplateObject implements TemplateInfo { TemplateEvent templEvent = null; if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { templEvent = TemplateEvent.CreateRequested; + } else if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested){ + templEvent = TemplateEvent.DestroyRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { templEvent = TemplateEvent.OperationSucceeded; } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { templEvent = TemplateEvent.OperationFailed; } - + if (templEvent != null) { this.stateTransit(templEvent); } } - + ojbectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); @@ -225,16 +227,18 @@ public class TemplateObject implements TemplateInfo { templateVO.setFormat(newTemplate.getFormat()); this.imageDao.update(templateVO.getId(), templateVO); } - + TemplateEvent templEvent = null; if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { templEvent = TemplateEvent.CreateRequested; - } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { + } else if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested){ + templEvent = TemplateEvent.DestroyRequested; + } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { templEvent = TemplateEvent.OperationSucceeded; } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { templEvent = TemplateEvent.OperationFailed; } - + if (templEvent != null) { this.stateTransit(templEvent); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 82d29f1a04d..462537f3ff8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -108,6 +108,9 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { State.Destroyed); stateMachines.addTransition(State.Destroying, Event.OperationFailed, State.Destroying); + //TODO: further investigate why an extra event is sent when it is alreay Ready + stateMachines.addTransition(State.Ready, Event.OperationSuccessed, + State.Ready); } @Override From 3b45bc9c3060d9aa0447fff4d1f71fee304d5533 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 8 May 2013 11:12:26 -0700 Subject: [PATCH 134/303] Make S3 register template work. --- core/src/com/cloud/storage/VMTemplateVO.java | 5 +++++ core/src/com/cloud/storage/template/DownloadManagerImpl.java | 3 +++ .../src/com/cloud/storage/template/S3TemplateDownloader.java | 4 ++-- .../org/apache/cloudstack/storage/test/S3TemplateTest.java | 5 +++++ engine/storage/integration-test/test/resource/testng.xml | 2 +- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/core/src/com/cloud/storage/VMTemplateVO.java b/core/src/com/cloud/storage/VMTemplateVO.java index e3339fdd6b4..06cb1b8f28b 100755 --- a/core/src/com/cloud/storage/VMTemplateVO.java +++ b/core/src/com/cloud/storage/VMTemplateVO.java @@ -421,6 +421,11 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject - + From dc5d2f45e9785a9c647e574ec99c3e3fd0798c02 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 8 May 2013 17:39:46 -0700 Subject: [PATCH 135/303] Make copyFromS3ToNFS flow work. --- .../resource/NfsSecondaryStorageResource.java | 30 ++++++++------- .../storage/datastore/db/ImageStoreDao.java | 1 + .../manager/StorageCacheManagerImpl.java | 37 +++++++++++-------- .../ImageStoreProviderManagerImpl.java | 12 ++---- .../storage/image/store/ImageStoreImpl.java | 3 +- .../storage/image/store/TemplateObject.java | 12 +++--- .../MockLocalNfsSecondaryStorageResource.java | 5 +++ .../storage/test/S3TemplateTest.java | 31 +++++++++++++--- .../image/datastore/ImageStoreHelper.java | 8 +++- .../storage/image/db/ImageStoreDaoImpl.java | 8 ++++ .../CloudStackImageStoreDriverImpl.java | 2 +- 11 files changed, 97 insertions(+), 52 deletions(-) diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 384a41af4a0..03e822ebbe7 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -231,9 +231,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, - - DataTO destData, NfsTO destImageStore) { + protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); @@ -288,8 +286,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new CopyCmdAnswer(errMsg); } } - - + + protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { String srcMountPoint = this.getRootDir(srcDataStore.getUrl()); String snapshotPath = srcData.getPath(); @@ -330,7 +328,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S loc.save(); TemplateObjectTO newTemplate = new TemplateObjectTO(); - newTemplate.setPath(destData.getPath() + File.separator + templateName); + newTemplate.setPath(destData.getPath() + File.separator + templateName); newTemplate.setFormat(ImageFormat.VHD); return new CopyCmdAnswer(newTemplate); } catch (ConfigurationException e) { @@ -346,16 +344,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new CopyCmdAnswer(errMsg); } - + protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { - + if (srcData.getHypervisorType() == HypervisorType.XenServer) { return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore); } return new CopyCmdAnswer(""); } - + protected Answer createTemplateFromSnapshot(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); @@ -366,7 +364,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.debug("only support nfs storage as src, when create template from snapshot"); return Answer.createUnsupportedCommandAnswer(cmd); } - + if (destDataStore instanceof NfsTO){ return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore); } @@ -380,12 +378,18 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); DataStoreTO destDataStore = destData.getDataStore(); - + if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) { return createTemplateFromSnapshot(cmd); } - + if (srcDataStore instanceof S3TO && destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache){ + S3TO s3 = (S3TO)srcDataStore; + NfsTO destImageStore = (NfsTO)destDataStore; + return this.copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore); + } + + return Answer.createUnsupportedCommandAnswer(cmd); } @@ -1729,7 +1733,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (_configIpFirewallScr != null) { s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr); } - + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh"); if (createTemplateFromSnapshotXenScript == null) { throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir()); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 8d6acbdf011..bc6e0293d9b 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -30,5 +30,6 @@ public interface ImageStoreDao extends GenericDao { public ImageStoreVO findByName(String name); public List findByProvider(String provider); public List findByScope(ZoneScope scope); + public List findImageCacheByScope(ZoneScope scope); } 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 index 1452e17a532..be1983e10eb 100644 --- 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 @@ -70,13 +70,13 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { @Override public void setName(String name) { // TODO Auto-generated method stub - + } @Override public void setConfigParams(Map params) { // TODO Auto-generated method stub - + } @Override @@ -94,7 +94,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { @Override public void setRunLevel(int level) { // TODO Auto-generated method stub - + } @Override @@ -113,9 +113,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { // TODO Auto-generated method stub return true; } - - + + private class CreateCacheObjectContext extends AsyncRpcConext { final AsyncCallFuture future; /** @@ -125,29 +125,34 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { super(callback); this.future = future; } - + } @Override public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); + AsyncCallFuture future = new AsyncCallFuture(); + /* CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - + caller.setCallback(future); + */ + CopyCommandResult result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); - - dataMotionSvr.copyAsync(data, objOnCacheStore, caller); + + dataMotionSvr.copyAsync(data, objOnCacheStore, future); result = future.get(); - + if (result.isFailed()) { cacheStore.delete(data); } else { objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); + return objOnCacheStore; } } catch (InterruptedException e) { s_logger.debug("create cache storage failed: " + e.toString()); @@ -160,19 +165,19 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { cacheStore.delete(data); } } - + return null; } - + @Override public DataObject getCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - + return objOnCacheStore; } - - protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, + + protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, CreateCacheObjectContext context) { AsyncCallFuture future = context.future; future.complete(callback.getResult()); 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 c14e2d91af6..a3dd930e1a8 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 @@ -124,17 +124,13 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager @Override public List listImageCacheStores(Scope scope) { - List imageStores = new ArrayList(); if (scope.getScopeType() != ScopeType.ZONE) { s_logger.debug("only support zone wide image cache stores"); - return imageStores; + return null; } - SearchCriteriaService 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 cacheStores = sc.list(); - for (ImageStoreVO store : cacheStores) { + List stores = dataStoreDao.findImageCacheByScope(new ZoneScope(scope.getScopeId())); + List imageStores = new ArrayList(); + for (ImageStoreVO store : stores) { imageStores.add(getImageStore(store.getId())); } return imageStores; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 638e1351947..5afe059616f 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -85,8 +85,7 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public DataStoreRole getRole() { - // TODO Auto-generated method stub - return DataStoreRole.Image; + return this.imageDataStoreVO.getRole(); } @Override public long getId() { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 61a81255a3d..daf85681848 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -186,7 +186,7 @@ public class TemplateObject implements TemplateInfo { templEvent = TemplateEvent.OperationFailed; } - if (templEvent != null) { + if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { this.stateTransit(templEvent); } } @@ -223,9 +223,11 @@ public class TemplateObject implements TemplateInfo { templateStoreRef.setDownloadPercent(100); templateStoreRef.setDownloadState(Status.DOWNLOADED); templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); - VMTemplateVO templateVO = this.imageDao.findById(this.getId()); - templateVO.setFormat(newTemplate.getFormat()); - this.imageDao.update(templateVO.getId(), templateVO); + if (this.getDataStore().getRole() == DataStoreRole.Image) { + VMTemplateVO templateVO = this.imageDao.findById(this.getId()); + templateVO.setFormat(newTemplate.getFormat()); + this.imageDao.update(templateVO.getId(), templateVO); + } } TemplateEvent templEvent = null; @@ -239,7 +241,7 @@ public class TemplateObject implements TemplateInfo { templEvent = TemplateEvent.OperationFailed; } - if (templEvent != null) { + if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { this.stateTransit(templEvent); } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index 0a460466036..d7a5d3fd1f5 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -65,6 +65,11 @@ public class MockLocalNfsSecondaryStorageResource extends } + @Override + public String getRootDir(String secUrl){ + return "/mnt"; + } + @Override public Answer executeRequest(Command cmd) { if (cmd instanceof DownloadSystemTemplateCommand){ diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java index 5f29fde529e..8c4eae5cbf0 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java @@ -1,6 +1,5 @@ package org.apache.cloudstack.storage.test; -import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -12,11 +11,14 @@ import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource; @@ -28,15 +30,14 @@ import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertNotNull; import com.cloud.dc.DataCenterVO; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.download.DownloadMonitorImpl; @@ -65,6 +66,8 @@ public class S3TemplateTest extends CloudStackTestNGBase { DownloadMonitorImpl downloadMonitor; @Inject ImageStoreHelper imageStoreHelper; + @Inject + StorageCacheManager cacheMgr; long dcId; long templateId; @@ -77,7 +80,6 @@ public class S3TemplateTest extends CloudStackTestNGBase { dc = dcDao.persist(dc); dcId = dc.getId(); - // add s3 image store Map sParams = new HashMap(); sParams.put("name", "test"); @@ -92,6 +94,17 @@ public class S3TemplateTest extends CloudStackTestNGBase { sDetails.put(ApiConstants.S3_END_POINT, this.getS3EndPoint()); this.imageStoreHelper.createImageStore(sParams, sDetails); + // add nfs cache storage + Map cParams = new HashMap(); + cParams.put("name", "testCache"); + cParams.put("protocol", "nfs"); + cParams.put("providerName", DataStoreProvider.NFS_IMAGE); + cParams.put("scope", ScopeType.ZONE); + cParams.put("role", DataStoreRole.ImageCache); + cParams.put("url", this.getSecondaryStorage()); + cParams.put("zoneId", dcId); + this.imageStoreHelper.createImageStore(cParams); + VMTemplateVO image = new VMTemplateVO(); image.setTemplateType(TemplateType.SYSTEM); @@ -119,9 +132,10 @@ public class S3TemplateTest extends CloudStackTestNGBase { ep.setResource(new MockLocalNfsSecondaryStorageResource()); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); } - @Test + @Test(priority = 1) public void registerTemplate() { TemplateInfo template = templateFactory.getTemplate(templateId); DataStore store = dataStoreMgr.getImageStore(dcId); @@ -141,4 +155,11 @@ public class S3TemplateTest extends CloudStackTestNGBase { } } + @Test(priority = 2) + public void copyTemplateToCache() { + TemplateInfo template = templateFactory.getTemplate(templateId); + DataObject cacheObj = this.cacheMgr.createCacheObject(template, new ZoneScope(dcId)); + assertNotNull(cacheObj, "failed to create cache object"); + } + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index d0dfd55ff37..deb702f3571 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -48,18 +48,22 @@ public class ImageStoreHelper { return store; } store = new ImageStoreVO(); - store.setName((String)params.get("name")); store.setProtocol((String)params.get("protocol")); store.setProviderName((String)params.get("providerName")); store.setScope((ScopeType)params.get("scope")); + store.setDataCenterId((Long)params.get("zoneId")); String uuid = (String)params.get("uuid"); if (uuid != null) { store.setUuid(uuid); } else { store.setUuid(UUID.randomUUID().toString()); } + store.setName((String)params.get("name")); + if ( store.getName() == null ){ + store.setName(store.getUuid()); + } store.setUrl((String)params.get("url")); - store.setRole(DataStoreRole.getRole((String)params.get("role"))); + store.setRole((DataStoreRole)params.get("role")); store = imageStoreDao.persist(store); return store; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 2300649bd86..06b286f5016 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -87,5 +87,13 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem return listBy(sc); } + @Override + public List findImageCacheByScope(ZoneScope scope) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.ImageCache); + sc.addAnd("scope", SearchCriteria.Op.EQ, ScopeType.ZONE); + sc.addAnd("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + return listBy(sc); + } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 84c5ea53994..1865068ac55 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -126,7 +126,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { public DataStoreTO getStoreTO(DataStore store) { ImageStoreImpl nfsStore = (ImageStoreImpl)store; NfsTO nfsTO = new NfsTO(); - nfsTO.setRole(DataStoreRole.Image); + nfsTO.setRole(store.getRole()); nfsTO.setUrl(nfsStore.getUri()); return nfsTO; } From 8ad517c0280c00f9aca6b968d1e86848733d60a2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 8 May 2013 17:58:52 -0700 Subject: [PATCH 136/303] Append template unique name for S3 key for template sync. --- core/src/com/cloud/storage/template/DownloadManagerImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 7aea5ba1642..651dea1af46 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -491,6 +491,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager throw new CloudRuntimeException("Unable to download from URL: " + url); } DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); + dj.setTmpltPath(installPathPrefix); jobs.put(jobId, dj); threadPool.execute(td); @@ -665,6 +666,9 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } else { installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; } + } else if (dstore instanceof S3TO ){ + // S3 key has template name inside to help template sync + installPathPrefix = installPathPrefix + File.separator + cmd.getName(); } String user = null; String password = null; From 545d2e4eb6c13e1931318d66dec9b48bf5a32429 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 8 May 2013 18:04:02 -0700 Subject: [PATCH 137/303] Change removed field annotation in TemplateJoinVO to remove workaround for not showing removed entries. --- server/src/com/cloud/api/query/QueryManagerImpl.java | 4 ++-- server/src/com/cloud/api/query/vo/TemplateJoinVO.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 807f2d64f1b..9af2715e84d 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2681,8 +2681,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); } - // don't return removed template - sc.addAnd("removed", SearchCriteria.Op.NULL); + // don't return removed template, this should not be needed since we changed annotation for removed field in TemplateJoinVO. + //sc.addAnd("removed", SearchCriteria.Op.NULL); // search unique templates and find details by Ids Pair, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index 0a6b0f9977c..77ce14afc1a 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -83,7 +83,7 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="created_on_store") private Date createdOnStore = null; - @Column(name=GenericDao.REMOVED) + @Column(name=GenericDao.REMOVED_COLUMN) @Temporal(TemporalType.TIMESTAMP) private Date removed; From fa1157521238d26bfa572c963adb5b3497f1a2c8 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 8 May 2013 22:06:07 -0700 Subject: [PATCH 138/303] Add store_role to template_store_ref, and add search function to find template_store_ref entry based on DataStoreRole and ZoneId. --- .../api/storage/TemplateDataFactory.java | 5 +- .../datastore/db/TemplateDataStoreDao.java | 5 +- .../datastore/db/TemplateDataStoreVO.java | 133 ++++++++++-------- .../image/TemplateDataFactoryImpl.java | 23 ++- .../storage/image/TemplateServiceImpl.java | 9 +- .../storage/test/S3TemplateTest.java | 4 +- .../cloudstack/storage/test/SnapshotTest.java | 18 +-- .../cloudstack/storage/test/TemplateTest.java | 6 +- .../cloudstack/storage/test/VolumeTest.java | 64 ++++----- .../ObjectInDataStoreManagerImpl.java | 4 +- .../image/db/TemplateDataStoreDaoImpl.java | 34 ++++- .../com/cloud/storage/VolumeManagerImpl.java | 4 +- .../storage/download/DownloadMonitorImpl.java | 1 + .../cloud/template/TemplateManagerImpl.java | 4 +- setup/db/db/schema-410to420.sql | 1 + 15 files changed, 191 insertions(+), 124 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java index c2775a351e8..8916f6681cf 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java @@ -18,9 +18,12 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.storage.DataStoreRole; + public interface TemplateDataFactory { TemplateInfo getTemplate(long templateId, DataStore store); TemplateInfo getTemplate(DataObject obj, DataStore store); - TemplateInfo getTemplate(long templateId); + TemplateInfo getTemplate(long templateId, DataStoreRole storeRole); + TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index f08f76d8b0f..dbb8dbdbc6d 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; @@ -50,7 +51,9 @@ public interface TemplateDataStoreDao extends GenericDao listByTemplate(long templateId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index 6347e613e67..ea50d88f978 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -33,6 +33,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; @@ -55,6 +56,10 @@ public class TemplateDataStoreVO implements StateObject future = new AsyncCallFuture(); templateSvr.createTemplateAsync(template, store, future); @@ -157,7 +157,7 @@ public class S3TemplateTest extends CloudStackTestNGBase { @Test(priority = 2) public void copyTemplateToCache() { - TemplateInfo template = templateFactory.getTemplate(templateId); + TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); DataObject cacheObj = this.cacheMgr.createCacheObject(template, new ZoneScope(dcId)); assertNotNull(cacheObj, "failed to create cache object"); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 9dc68546005..acd32b49701 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -240,7 +240,7 @@ public class SnapshotTest extends CloudStackTestNGBase { DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); - TemplateInfo template = templateFactory.getTemplate(image.getId()); + TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image); DataObject templateOnStore = store.create(template); TemplateObjectTO to = new TemplateObjectTO(); to.setPath(this.getImageInstallPath()); @@ -313,7 +313,7 @@ public class SnapshotTest extends CloudStackTestNGBase { return null; } } - + private SnapshotVO createSnapshotInDb(VolumeInfo volume) { Snapshot.Type snapshotType = Snapshot.Type.MANUAL; SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID().toString(), @@ -336,7 +336,7 @@ public class SnapshotTest extends CloudStackTestNGBase { primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId())); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); VolumeApiResult result; try { @@ -351,7 +351,7 @@ public class SnapshotTest extends CloudStackTestNGBase { } return null; } - + @Test public void createSnapshot() { VolumeInfo vol = createCopyBaseImage(); @@ -363,11 +363,11 @@ public class SnapshotTest extends CloudStackTestNGBase { } } } - + private VMTemplateVO createTemplateInDb() { image = new VMTemplateVO(); image.setTemplateType(TemplateType.USER); - + image.setUniqueName(UUID.randomUUID().toString()); image.setName(UUID.randomUUID().toString()); image.setPublicTemplate(true); @@ -385,7 +385,7 @@ public class SnapshotTest extends CloudStackTestNGBase { image = imageDataDao.persist(image); return image; } - + @Test public void createTemplateFromSnapshot() { VolumeInfo vol = createCopyBaseImage(); @@ -398,13 +398,13 @@ public class SnapshotTest extends CloudStackTestNGBase { result = true; } } - + AssertJUnit.assertTrue(result); LocalHostEndpoint ep = new LocalHostEndpoint(); ep.setResource(new MockLocalNfsSecondaryStorageResource()); Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); VMTemplateVO templateVO = createTemplateInDb(); - TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId()); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index 294d4b5a2c2..ad4313a1618 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -68,7 +68,7 @@ public class TemplateTest extends CloudStackTestNGBase { @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); - + //create data center DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); @@ -117,7 +117,7 @@ public class TemplateTest extends CloudStackTestNGBase { @Test public void registerTemplate() { - TemplateInfo template = templateFactory.getTemplate(templateId); + TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); DataStore store = dataStoreMgr.getImageStore(dcId); AsyncCallFuture future = new AsyncCallFuture(); templateSvr.createTemplateAsync(template, store, future); @@ -137,7 +137,7 @@ public class TemplateTest extends CloudStackTestNGBase { // @Test public void deleteTemplate() { - TemplateInfo template = templateFactory.getTemplate(templateId); + TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); DataStore store = dataStoreMgr.getImageStore(dcId); AsyncCallFuture future = new AsyncCallFuture(); templateSvr.deleteTemplateAsync(template); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index a35495999d4..fe628794b94 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -146,7 +146,7 @@ public class VolumeTest extends CloudStackTestNGBase { @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); - + host = hostDao.findByGuid(this.getHostGuid()); if (host != null) { dcId = host.getDataCenterId(); @@ -188,7 +188,7 @@ public class VolumeTest extends CloudStackTestNGBase { host.setClusterId(cluster.getId()); host = hostDao.persist(host); - + imageStore = new ImageStoreVO(); imageStore.setName(imageStoreName); imageStore.setDataCenterId(dcId); @@ -199,7 +199,7 @@ public class VolumeTest extends CloudStackTestNGBase { imageStore.setProtocol("nfs"); imageStore = imageStoreDao.persist(imageStore); } - + image = new VMTemplateVO(); image.setTemplateType(TemplateType.USER); image.setUrl(this.getTemplateUrl()); @@ -219,9 +219,9 @@ public class VolumeTest extends CloudStackTestNGBase { image.setExtractable(true); image = imageDataDao.persist(image); - + /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); - + templateStore.setDataStoreId(imageStore.getId()); templateStore.setDownloadPercent(100); templateStore.setDownloadState(Status.DOWNLOADED); @@ -229,32 +229,32 @@ public class VolumeTest extends CloudStackTestNGBase { templateStore.setInstallPath(this.getImageInstallPath()); templateStore.setTemplateId(image.getId()); templateStoreDao.persist(templateStore);*/ - - + + DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); - TemplateInfo template = templateFactory.getTemplate(image.getId()); + TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image); DataObject templateOnStore = store.create(template); TemplateObjectTO to = new TemplateObjectTO(); to.setPath(this.getImageInstallPath()); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); - - + + } - + @Override protected void injectMockito() { List hosts = new ArrayList(); hosts.add(this.host); Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); - + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); } - + public DataStore createPrimaryDataStore() { try { String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString(); @@ -262,7 +262,7 @@ public class VolumeTest extends CloudStackTestNGBase { if (pools.size() > 0) { return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); } - + /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); Map params = new HashMap(); URI uri = new URI(this.getPrimaryStorageUrl()); @@ -283,7 +283,7 @@ public class VolumeTest extends CloudStackTestNGBase { DataStore store = lifeCycle.initialize(params); ClusterScope scope = new ClusterScope(clusterId, podId, dcId); lifeCycle.attachCluster(store, scope);*/ - + StoragePoolVO pool = new StoragePoolVO(); pool.setClusterId(clusterId); pool.setDataCenterId(dcId); @@ -305,14 +305,14 @@ public class VolumeTest extends CloudStackTestNGBase { return null; } } - + private VolumeVO createVolume(Long templateId, long dataStoreId) { VolumeVO volume = new VolumeVO(1000, new RootDisk().toString(), UUID.randomUUID().toString(), templateId); volume.setPoolId(dataStoreId); volume = volumeDao.persist(volume); return volume; } - + //@Test public void testCopyBaseImage() { DataStore primaryStore = createPrimaryDataStore(); @@ -320,12 +320,12 @@ public class VolumeTest extends CloudStackTestNGBase { primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId())); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); try { VolumeApiResult result = future.get(); - + AssertJUnit.assertTrue(result.isSuccess()); - + VolumeInfo newVol = result.getVolume(); this.volumeService.destroyVolume(newVol.getId()); VolumeInfo vol = this.volFactory.getVolume(volume.getId()); @@ -341,7 +341,7 @@ public class VolumeTest extends CloudStackTestNGBase { e.printStackTrace(); } } - + @Test public void testCreateDataDisk() { DataStore primaryStore = createPrimaryDataStore(); @@ -351,7 +351,7 @@ public class VolumeTest extends CloudStackTestNGBase { VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); this.volumeService.createVolumeAsync(volInfo, primaryStore); } - + @Test public void testDeleteDisk() { DataStore primaryStore = createPrimaryDataStore(); @@ -363,7 +363,7 @@ public class VolumeTest extends CloudStackTestNGBase { try { VolumeApiResult result = future.get(); VolumeInfo vol = result.getVolume(); - + this.volumeService.destroyVolume(volInfo.getId()); volInfo = this.volFactory.getVolume(vol.getId()); this.volumeService.expungeVolumeAsync(volInfo); @@ -377,13 +377,13 @@ public class VolumeTest extends CloudStackTestNGBase { // TODO Auto-generated catch block e.printStackTrace(); } - + } - + private VMTemplateVO createTemplateInDb() { image = new VMTemplateVO(); image.setTemplateType(TemplateType.USER); - + image.setUniqueName(UUID.randomUUID().toString()); image.setName(UUID.randomUUID().toString()); image.setPublicTemplate(true); @@ -401,7 +401,7 @@ public class VolumeTest extends CloudStackTestNGBase { image = imageDataDao.persist(image); return image; } - + @Test public void testCreateTemplateFromVolume() { DataStore primaryStore = createPrimaryDataStore(); @@ -412,13 +412,13 @@ public class VolumeTest extends CloudStackTestNGBase { AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); try { VolumeApiResult result = future.get(); - + AssertJUnit.assertTrue(result.isSuccess()); volInfo = result.getVolume(); VMTemplateVO templateVO = createTemplateInDb(); - TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId()); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); - + this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -427,7 +427,7 @@ public class VolumeTest extends CloudStackTestNGBase { // TODO Auto-generated catch block e.printStackTrace(); } - - + + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 462537f3ff8..f0b54e1cb3c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -303,7 +303,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { DataObjectInStore vo = null; switch (type){ case TEMPLATE: - vo = templateDataStoreDao.findByTemplate(objId); + vo = templateDataStoreDao.findByTemplate(objId, role); break; case SNAPSHOT: vo = snapshotDataStoreDao.findBySnapshot(objId, role); @@ -313,7 +313,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { break; } if (vo != null) { - store = this.storeMgr.getDataStore(vo.getDataStoreId(), DataStoreRole.Image); + store = this.storeMgr.getDataStore(vo.getDataStoreId(), role); } } return store; diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index aa84821325a..345098c6898 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -35,6 +35,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; @@ -51,6 +52,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; private SearchBuilder templateSearch; + private SearchBuilder templateRoleSearch; private SearchBuilder storeTemplateSearch; private SearchBuilder storeTemplateStateSearch; private SearchBuilder storeTemplateDownloadStatusSearch; @@ -73,6 +75,12 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = templateSearch.create(); + public TemplateDataStoreVO findByTemplate(long templateId, DataStoreRole role) { + SearchCriteria sc = templateRoleSearch.create(); sc.setParameters("template_id", templateId); + sc.setParameters("store_role", role); sc.setParameters("destroyed", false); return findOneIncludingRemovedBy(sc); } @@ -279,6 +289,24 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase imgStores = null; + if ( role == DataStoreRole.Image){ + imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); + } else if (role == DataStoreRole.ImageCache){ + imgStores = this._storeMgr.getImageCacheStores(new ZoneScope(zoneId)); + } + if ( imgStores != null ){ + for (DataStore store : imgStores){ + List sRes = this.listByTemplateStore(templateId, store.getId()); + if ( sRes != null && sRes.size() > 0){ + return sRes.get(0); + } + } + } + return null; + } } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 828f34a71aa..90b2366130e 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -671,7 +671,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (isNotCreatedFromTemplate) { future = this.volService.createVolumeAsync(volume, store); } else { - TemplateInfo templ = this.tmplFactory.getTemplate(template.getId()); + TemplateInfo templ = this.tmplFactory.getTemplate(template.getId(), DataStoreRole.Image); future = this.volService.createVolumeFromTemplateAsync(volume, store.getId(), templ); } try { @@ -2266,7 +2266,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (templateId == null) { future = this.volService.createVolumeAsync(volume, destPool); } else { - TemplateInfo templ = this.tmplFactory.getTemplate(templateId); + TemplateInfo templ = this.tmplFactory.getTemplate(templateId, DataStoreRole.Image); future = this.volService.createVolumeFromTemplateAsync(volume, destPool.getId(), templ); } VolumeApiResult result = null; diff --git a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java index 09dbae3dadd..9168aad4088 100755 --- a/server/src/com/cloud/storage/download/DownloadMonitorImpl.java +++ b/server/src/com/cloud/storage/download/DownloadMonitorImpl.java @@ -174,6 +174,7 @@ public class DownloadMonitorImpl extends ManagerBase implements DownloadMonitor if (vmTemplateStore == null) { vmTemplateStore = new TemplateDataStoreVO(store.getId(), template.getId(), new Date(), 0, VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED, null, null, "jobid0000", null, template.getUri()); + vmTemplateStore.setDataStoreRole(store.getRole()); _vmTemplateStoreDao.persist(vmTemplateStore); } else if ((vmTemplateStore.getJobId() != null) && (vmTemplateStore.getJobId().length() > 2)) { downloadJobExists = true; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 46c4c0a8605..20cdce16c36 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1348,7 +1348,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, VolumeVO volume = null; try { - TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId); + TemplateInfo tmplInfo = this._tmplFactory.getTemplate(templateId, DataStoreRole.Image); Long zoneId = null; if (snapshotId != null) { snapshot = _snapshotDao.findById(snapshotId); @@ -1384,7 +1384,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.debug("Failed to create template" + result.getResult()); throw new CloudRuntimeException("Failed to create template" + result.getResult()); } - + VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date()); this._tmpltZoneDao.persist(templateZone); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index a88af23e81e..6ce0d2defee 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -128,6 +128,7 @@ CREATE TABLE `cloud`.`template_store_ref` ( `job_id` varchar(255), `download_pct` int(10) unsigned, `size` bigint unsigned, + `store_role` varchar(255), `physical_size` bigint unsigned DEFAULT 0, `download_state` varchar(255), `error_str` varchar(255), From 292e77b96b0a518765a5065320cec45bf87ef1ec Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 9 May 2013 16:19:06 -0700 Subject: [PATCH 139/303] Fix marvin test to add S3 image store and cache storage. --- client/tomcatconf/commands.properties.in | 1 + .../LocalNfsSecondaryStorageResource.java | 4 + .../cloudstack/storage/LocalHostEndpoint.java | 2 +- .../cloud/server/ManagementServerImpl.java | 1 + setup/db/db/schema-410to420.sql | 3 +- tools/devcloud/devcloud.cfg | 2 +- tools/devcloud/devcloud_s3.cfg | 141 ++++++++++++++++++ tools/marvin/marvin/configGenerator.py | 7 + tools/marvin/marvin/deployDataCenter.py | 21 ++- 9 files changed, 177 insertions(+), 5 deletions(-) create mode 100644 tools/devcloud/devcloud_s3.cfg diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 002da875cae..c93512262b2 100644 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -245,6 +245,7 @@ listS3s=1 addImageStore=1 listImageStores=1 deleteImageStore=1 +createCacheStore=1 #### host commands addHost=3 diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index a2cf757b432..4c708af91d5 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -32,6 +32,10 @@ import com.cloud.utils.exception.CloudRuntimeException; public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { + public LocalNfsSecondaryStorageResource(){ + this._dlMgr = new DownloadManagerImpl(); + } + @Override public Answer executeRequest(Command cmd) { if (cmd instanceof DownloadSystemTemplateCommand){ diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 1ae13b630d0..d689f36dfe6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -23,7 +23,7 @@ public class LocalHostEndpoint implements EndPoint { private ScheduledExecutorService executor; ServerResource resource; public LocalHostEndpoint() { - resource = ComponentContext.inject(LocalNfsSecondaryStorageResource.class); + resource = new LocalNfsSecondaryStorageResource(); executor = Executors.newScheduledThreadPool(10); } @Override diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 92d8c7bc606..b0f0fcb9709 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -2153,6 +2153,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe cmdList.add(AddImageStoreCmd.class); cmdList.add(ListImageStoresCmd.class); cmdList.add(DeleteImageStoreCmd.class); + cmdList.add(CreateCacheStoreCmd.class); return cmdList; } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 6ce0d2defee..75d29f65e8d 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -115,7 +115,8 @@ CREATE VIEW `cloud`.`image_store_view` AS left join `cloud`.`data_center` ON image_store.data_center_id = data_center.id left join - `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id; + `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id + where image_store.role = 'Image'; -- here we have to allow null for store_id to accomodate baremetal case to search for ready templates since template state is only stored in this table -- FK also commented out due to this diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg index 0be6026a822..a2a9fd82791 100644 --- a/tools/devcloud/devcloud.cfg +++ b/tools/devcloud/devcloud.cfg @@ -84,7 +84,7 @@ "secondaryStorages": [ { "url": "nfs://192.168.56.10/opt/storage/secondary", - "providerName": "CloudStack ImageStore Provider", + "providerName": "NFS", "details": { } } diff --git a/tools/devcloud/devcloud_s3.cfg b/tools/devcloud/devcloud_s3.cfg new file mode 100644 index 00000000000..885f54aa110 --- /dev/null +++ b/tools/devcloud/devcloud_s3.cfg @@ -0,0 +1,141 @@ +# 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. +# + +{ + "zones": [ + { + "name": "DevCloud0", + "physical_networks": [ + { + "broadcastdomainrange": "Zone", + "name": "test-network", + "traffictypes": [ + { + "typ": "Guest" + }, + { + "typ": "Management" + } + ], + "providers": [ + { + "broadcastdomainrange": "ZONE", + "name": "VirtualRouter" + }, + { + "broadcastdomainrange": "Pod", + "name": "SecurityGroupProvider" + } + ] + } + ], + "dns2": "4.4.4.4", + "dns1": "8.8.8.8", + "securitygroupenabled": "true", + "localstorageenabled": "true", + "networktype": "Basic", + "pods": [ + { + "endip": "192.168.56.220", + "name": "test00", + "startip": "192.168.56.200", + "guestIpRanges": [ + { + "startip": "192.168.56.100", + "endip": "192.168.56.199", + "netmask": "255.255.255.0", + "gateway": "192.168.56.1" + } + ], + "netmask": "255.255.255.0", + "clusters": [ + { + "clustername": "test000", + "hypervisor": "XenServer", + "hosts": [ + { + "username": "root", + "url": "http://192.168.56.10/", + "password": "password" + } + ], + "clustertype": "CloudManaged" + } + ], + "gateway": "192.168.56.1" + } + ], + "internaldns1": "192.168.56.1", + "secondaryStorages": [ + { + "providerName": "S3", + "details": [ + { + "key" : "accesskey", + "value" :"OYAZXCAFUC1DAFOXNJWI" + }, + { + "key" : "secretkey", + "value" : "OYAZXCAFUC1DAFOXNJWI" + }, + { + "key" : "endpoint", + "value" : "10.223.89.7:8080" + }, + { + "key" : "bucket", + "value" : "cloudstack" + } + ] + } + ], + "cacheStorages": [ + { + "url": "nfs://192.168.56.10/opt/storage/cache", + "providerName": "NFS", + "details": [ + ] + } + ] + } + ], + "logger": [ + { + "name": "TestClient", + "file": "/tmp/testclient.log" + }, + { + "name": "TestCase", + "file": "/tmp/testcase.log" + } + ], + "mgtSvr": [ + { + "mgtSvrIp": "127.0.0.1", + "port": 8096 + } + ], + "dbSvr": + { + "dbSvr": "127.0.0.1", + "port": 3306, + "user": "cloud", + "passwd": "cloud", + "db": "cloud" + } +} diff --git a/tools/marvin/marvin/configGenerator.py b/tools/marvin/marvin/configGenerator.py index 8235b095ca1..adb8f541391 100644 --- a/tools/marvin/marvin/configGenerator.py +++ b/tools/marvin/marvin/configGenerator.py @@ -70,6 +70,7 @@ class zone(): self.physical_networks = [] self.pods = [] self.secondaryStorages = [] + self.cacheStorages = [] class traffictype(): @@ -182,6 +183,12 @@ class secondaryStorage(): self.providerName = None self.details = None +class cacheStorage(): + def __init__(self): + self.url = None + self.providerName = None + self.details = None + class s3(): def __init__(self): self.accesskey = None diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index aaf05011dc1..164af74adc0 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -141,10 +141,26 @@ class deployDataCenters(): secondarycmd = addImageStore.addImageStoreCmd() secondarycmd.url = secondary.url secondarycmd.provider = secondary.providerName - """if secondary.provider == "CloudStack ImageStore Provider":""" - secondarycmd.zoneid = zoneId + secondarycmd.details = [] + for item in secondary.details: + secondarycmd.details.append(item.__dict__) + if secondarycmd.provider == "NFS": + secondarycmd.zoneid = zoneId self.apiClient.addImageStore(secondarycmd) + def createCacheStorages(self, cacheStorages, zoneId): + if cacheStorages is None: + return + for cache in cacheStorages: + cachecmd = createCacheStore.createCacheStoreCmd() + cachecmd.url = cache.url + cachecmd.provider = cache.providerName + cachecmd.zoneid = zoneId + cachecmd.details = [] + for item in cache.details: + cachecmd.details.append(item.__dict__) + self.apiClient.createCacheStore(cachecmd) + def createnetworks(self, networks, zoneId): if networks is None: return @@ -322,6 +338,7 @@ class deployDataCenters(): zoneId) self.createSecondaryStorages(zone.secondaryStorages, zoneId) + self.createCacheStorages(zone.cacheStorages, zoneId) self.enableZone(zoneId, "Enabled") return From 1e539e81e3fc4e3736947740f43406a2407aca70 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 9 May 2013 17:48:00 -0700 Subject: [PATCH 140/303] CLOUDSTACK-2351: object store - UI - infrastructure menu - secondary storage - Add Secondary Storage - when provider is S3, show option to create NFS cache storage. --- ui/scripts/system.js | 67 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 3 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index fedef35a14f..cfa591dc2db 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -10380,7 +10380,11 @@ $form.find('.form-item[rel=connectiontimeout]').hide(); $form.find('.form-item[rel=maxerrorretry]').hide(); $form.find('.form-item[rel=sockettimeout]').hide(); - + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + //Swift $form.find('.form-item[rel=url]').hide(); $form.find('.form-item[rel=account]').hide(); @@ -10401,7 +10405,14 @@ $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); - $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + + $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked','checked'); + $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); + //Swift $form.find('.form-item[rel=url]').hide(); @@ -10424,7 +10435,11 @@ $form.find('.form-item[rel=connectiontimeout]').hide(); $form.find('.form-item[rel=maxerrorretry]').hide(); $form.find('.form-item[rel=sockettimeout]').hide(); - + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + //Swift $form.find('.form-item[rel=url]').css('display', 'inline-block'); $form.find('.form-item[rel=account]').css('display', 'inline-block'); @@ -10499,6 +10514,52 @@ connectiontimeout: { label: 'label.s3.connection_timeout' }, maxerrorretry: { label: 'label.s3.max_error_retry' }, sockettimeout: { label: 'label.s3.socket_timeout' }, + + createNfsCache: { + label: 'Create NFS Cache Storage', + isBoolean: true, + isChecked: true + }, + nfsCacheZoneid: { + dependsOn: 'createNfsCache', + label: 'Zone', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } + } + }); + } + }, + nfsCacheNfsServer: { + dependsOn: 'createNfsCache', + label: 'label.nfs.server', + validation: { required: true } + }, + nfsCachePath: { + dependsOn: 'createNfsCache', + label: 'label.path', + validation: { required: true } + }, //S3 (end) From 0824be38ff30fe348cd75484c6f9a91a478b4029 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 9 May 2013 19:07:03 -0700 Subject: [PATCH 141/303] Fix a bug where listImageStores also shows cacheStorage. --- server/src/com/cloud/api/query/QueryManagerImpl.java | 3 +++ .../src/com/cloud/api/query/vo/ImageStoreJoinVO.java | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index 9af2715e84d..06a39c48c04 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -142,6 +142,7 @@ import com.cloud.server.Criteria; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; @@ -1973,9 +1974,11 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sb.and("dataCenterId", sb.entity().getZoneId(), SearchCriteria.Op.EQ); sb.and("protocol", sb.entity().getProtocol(), SearchCriteria.Op.EQ); sb.and("provider", sb.entity().getProviderName(), SearchCriteria.Op.EQ); + sb.and("role", sb.entity().getRole(), SearchCriteria.Op.EQ); SearchCriteria sc = sb.create(); + sc.setParameters("role", DataStoreRole.Image); if (keyword != null) { diff --git a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java index a5ee007ecfb..7014e05ad39 100644 --- a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java @@ -23,6 +23,7 @@ import javax.persistence.Enumerated; import javax.persistence.Id; import javax.persistence.Table; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import org.apache.cloudstack.api.Identity; @@ -59,6 +60,10 @@ public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Id @Enumerated(value = EnumType.STRING) private ScopeType scope; + @Column(name = "role") + @Enumerated(value = EnumType.STRING) + private DataStoreRole role; + @Column(name="data_center_id") private long zoneId; @@ -176,6 +181,12 @@ public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Id this.detailValue = detailValue; } + public DataStoreRole getRole() { + return role; + } + public void setRole(DataStoreRole role) { + this.role = role; + } } From f965e2d89201d8fd5fc766f65bd5748d1ffaa49e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 9 May 2013 19:07:57 -0700 Subject: [PATCH 142/303] Download system template while adding S3 image store is working. --- .../resource/LocalNfsSecondaryStorageResource.java | 2 ++ .../com/cloud/storage/template/S3TemplateDownloader.java | 6 +++--- .../cloudstack/storage/image/TemplateServiceImpl.java | 4 +++- setup/db/db/schema-410to420.sql | 8 ++++++-- tools/devcloud/devcloud_s3.cfg | 2 +- 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index 4c708af91d5..b7278f7a5d4 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -10,6 +10,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.List; +import java.util.concurrent.Executors; import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; import org.springframework.stereotype.Component; @@ -34,6 +35,7 @@ public class LocalNfsSecondaryStorageResource extends public LocalNfsSecondaryStorageResource(){ this._dlMgr = new DownloadManagerImpl(); + ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); } @Override diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index b555ec2537f..43b582ccecf 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -279,9 +279,9 @@ public class S3TemplateDownloader implements TemplateDownloader { @Override public void progressChanged( ProgressEvent progressEvent) { - s_logger.info(progressEvent.getBytesTransfered() - + " number of byte transferd " - + new Date()); + // s_logger.debug(progressEvent.getBytesTransfered() + // + " number of byte transferd " + // + new Date()); totalBytes += progressEvent.getBytesTransfered(); if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) { s_logger.info("download completed"); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 988aaa7be2a..e18bac92280 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -477,7 +477,9 @@ public class TemplateServiceImpl implements TemplateService { return null; } - parentCallback.complete(result); + if (parentCallback != null){ + parentCallback.complete(result); + } return null; } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 75d29f65e8d..74f3388efbf 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -105,6 +105,7 @@ CREATE VIEW `cloud`.`image_store_view` AS image_store.protocol, image_store.url, image_store.scope, + image_store.role, data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, @@ -115,8 +116,8 @@ CREATE VIEW `cloud`.`image_store_view` AS left join `cloud`.`data_center` ON image_store.data_center_id = data_center.id left join - `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id - where image_store.role = 'Image'; + `cloud`.`image_store_details` ON image_store_details.store_id = image_store.id; + -- here we have to allow null for store_id to accomodate baremetal case to search for ready templates since template state is only stored in this table -- FK also commented out due to this @@ -732,3 +733,6 @@ CREATE VIEW `cloud`.`volume_view` AS `cloud`.`async_job` ON async_job.instance_id = volumes.id and async_job.instance_type = 'Volume' and async_job.job_status = 0; + + update `cloud`.`vm_template` set state='Allocated' where state is NULL; + update `cloud`.`vm_template` set update_count=0 where update_count is NULL; diff --git a/tools/devcloud/devcloud_s3.cfg b/tools/devcloud/devcloud_s3.cfg index 885f54aa110..ea5056469f6 100644 --- a/tools/devcloud/devcloud_s3.cfg +++ b/tools/devcloud/devcloud_s3.cfg @@ -91,7 +91,7 @@ }, { "key" : "secretkey", - "value" : "OYAZXCAFUC1DAFOXNJWI" + "value" : "YHpRtzNDwl12DtrQmwRvdpnf2xK2AeVM30rXxQ==" }, { "key" : "endpoint", From 6f4fcf741c864dbc6d0a1862eeff240a3e1640de Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 9 May 2013 21:43:52 -0700 Subject: [PATCH 143/303] Fix listImageStores to only list store with Image role, excluding those cache stores since they are also stored in image_store table. --- .../cloudstack/storage/datastore/db/ImageStoreDao.java | 2 +- .../image/manager/ImageStoreProviderManagerImpl.java | 2 +- .../cloudstack/storage/image/db/ImageStoreDaoImpl.java | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index bc6e0293d9b..4ac2ffc9c91 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -31,5 +31,5 @@ public interface ImageStoreDao extends GenericDao { public List findByProvider(String provider); public List findByScope(ZoneScope scope); public List findImageCacheByScope(ZoneScope scope); - + public List listImageStores(); } 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 a3dd930e1a8..43c02f6b6c2 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 @@ -92,7 +92,7 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager @Override public List listImageStores() { - List stores = dataStoreDao.listAll(); + List stores = dataStoreDao.listImageStores(); List imageStores = new ArrayList(); for (ImageStoreVO store : stores) { imageStores.add(getImageStore(store.getId())); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 06b286f5016..31cf39fb069 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -96,4 +96,12 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem return listBy(sc); } + @Override + public List listImageStores() { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.Image); + return listBy(sc); + } + + } From 2c22488ed747a8c54af8755188a0c13f56bbadc1 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 9 May 2013 21:46:43 -0700 Subject: [PATCH 144/303] Filter out cache store in find image store by provider. --- .../apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 31cf39fb069..d7478293fa2 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -73,6 +73,7 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem public List findByProvider(String provider) { SearchCriteria sc = providerSearch.create(); sc.setParameters("providerName", provider); + sc.setParameters("role", DataStoreRole.Image); return listBy(sc); } From a83b87b7e59767683ae10e9ec474321d354e0084 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 9 May 2013 22:49:14 -0700 Subject: [PATCH 145/303] Set template size for S3 template downloader. --- .../storage/template/DownloadManagerImpl.java | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/core/src/com/cloud/storage/template/DownloadManagerImpl.java b/core/src/com/cloud/storage/template/DownloadManagerImpl.java index 651dea1af46..fe1ae7f90d3 100755 --- a/core/src/com/cloud/storage/template/DownloadManagerImpl.java +++ b/core/src/com/cloud/storage/template/DownloadManagerImpl.java @@ -45,6 +45,7 @@ import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.cloudstack.storage.command.DownloadProgressCommand.RequestType; +import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import com.cloud.agent.api.storage.DownloadAnswer; @@ -226,12 +227,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private int installTimeoutPerGig = 180 * 60 * 1000; private boolean _sslCopy; - public void setThreadPool(ExecutorService threadPool) { this.threadPool = threadPool; } - public void setStorageLayer(StorageLayer storage){ + public void setStorageLayer(StorageLayer storage) { this._storage = storage; } @@ -286,9 +286,17 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager td.setStatus(Status.POST_DOWNLOAD_FINISHED); td.setDownloadError("Install completed successfully at " + new SimpleDateFormat().format(new Date())); } - } else{ - // for s3 and swift, we skip post download step and just set status to trigger callback. + } else { + // for s3 and swift, we skip post download step and just set + // status to trigger callback. td.setStatus(Status.POST_DOWNLOAD_FINISHED); + // set template size for S3 + if (td instanceof S3TemplateDownloader){ + long size = ((S3TemplateDownloader)td).totalBytes; + DownloadJob dnld = jobs.get(jobId); + dnld.setTemplatesize(size); + dnld.setTemplatePhysicalSize(size); + } } dj.cleanup(); break; @@ -336,8 +344,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private String postDownload(String jobId) { DownloadJob dnld = jobs.get(jobId); TemplateDownloader td = dnld.getTemplateDownloader(); - String resourcePath = dnld.getInstallPathPrefix(); // path with mount directory - String finalResourcePath = dnld.getTmpltPath(); // template download path on secondary storage + String resourcePath = dnld.getInstallPathPrefix(); // path with mount + // directory + String finalResourcePath = dnld.getTmpltPath(); // template download + // path on secondary + // storage ResourceType resourceType = dnld.getResourceType(); /* @@ -387,13 +398,15 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager templateName = java.util.UUID.nameUUIDFromBytes((jobs.get(jobId).getTmpltName() + System.currentTimeMillis()).getBytes()).toString(); } - // run script to mv the temporary template file to the final template file + // run script to mv the temporary template file to the final template + // file String templateFilename = templateName + "." + extension; dnld.setTmpltPath(finalResourcePath + "/" + templateFilename); scr.add("-n", templateFilename); scr.add("-t", resourcePath); - scr.add("-f", td.getDownloadLocalPath()); // this is the temporary template file downloaded + scr.add("-f", td.getDownloadLocalPath()); // this is the temporary + // template file downloaded if (dnld.getChecksum() != null && dnld.getChecksum().length() > 1) { scr.add("-c", dnld.getChecksum()); } @@ -500,7 +513,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager @Override public String downloadPublicTemplate(long id, String url, String name, ImageFormat format, boolean hvm, Long accountId, String descr, - String cksum, String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, ResourceType resourceType) { + String cksum, String installPathPrefix, String templatePath, String user, String password, long maxTemplateSizeInBytes, Proxy proxy, + ResourceType resourceType) { UUID uuid = UUID.randomUUID(); String jobId = uuid.toString(); String tmpDir = installPathPrefix; @@ -548,8 +562,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } else { throw new CloudRuntimeException("Unable to download from URL: " + url); } - // NOTE the difference between installPathPrefix and templatePath here. instalPathPrefix is the absolute path for template including mount directory - // on ssvm, while templatePath is the final relative path on secondary storage. + // NOTE the difference between installPathPrefix and templatePath + // here. instalPathPrefix is the absolute path for template + // including mount directory + // on ssvm, while templatePath is the final relative path on + // secondary storage. DownloadJob dj = new DownloadJob(td, jobId, id, name, format, hvm, accountId, descr, cksum, installPathPrefix, resourceType); dj.setTmpltPath(templatePath); jobs.put(jobId, dj); @@ -666,7 +683,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } else { installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; } - } else if (dstore instanceof S3TO ){ + } else if (dstore instanceof S3TO) { // S3 key has template name inside to help template sync installPathPrefix = installPathPrefix + File.separator + cmd.getName(); } @@ -685,7 +702,8 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager cmd.getDescription(), cmd.getChecksum(), installPathPrefix, user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); } else { jobId = downloadPublicTemplate(cmd.getId(), cmd.getUrl(), cmd.getName(), cmd.getFormat(), cmd.isHvm(), cmd.getAccountId(), - cmd.getDescription(), cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, cmd.getProxy(), resourceType); + cmd.getDescription(), cmd.getChecksum(), installPathPrefix, cmd.getInstallPath(), user, password, maxDownloadSizeInBytes, + cmd.getProxy(), resourceType); } sleep(); if (jobId == null) { From 42e25a22fc7140c68cda589e95d98dda3ba6cdf3 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 9 May 2013 23:09:42 -0700 Subject: [PATCH 146/303] refactor kvm/vmware resource code --- .../cloud/agent/api/to}/DataObjectType.java | 2 +- .../src/com/cloud/agent/api/to}/DataTO.java | 4 +- api/src/com/cloud/agent/api/to/DiskTO.java | 60 + .../cloud/agent/api/to/VirtualMachineTO.java | 6 +- .../com/cloud/vm/VirtualMachineProfile.java | 8 +- core/src/com/cloud/serializer/GsonHelper.java | 2 +- .../resource/NfsSecondaryStorageResource.java | 4 +- .../storage/resource/StorageProcessor.java | 45 + .../StorageSubsystemCommandHandler.java | 27 + .../StorageSubsystemCommandHandlerBase.java | 135 ++ .../subsystem/api/storage/DataObject.java | 2 + .../api/storage/DataStoreDriver.java | 1 + .../storage/command/AttachAnswer.java | 44 + .../storage/command/AttachCommand.java | 52 + .../storage/command/CopyCmdAnswer.java | 2 +- .../storage/command/CopyCommand.java | 2 +- .../storage/command/CreateObjectAnswer.java | 2 +- .../storage/command/CreateObjectCommand.java | 2 +- .../storage/command/DeleteCommand.java | 2 +- .../storage/command/DettachAnswer.java | 44 + .../storage/command/DettachCommand.java | 52 + .../storage/to/PrimaryDataStoreTO.java | 41 + .../storage/to/SnapshotObjectTO.java | 4 +- .../storage/to/TemplateObjectTO.java | 11 +- .../cloudstack/storage/to/VolumeObjectTO.java | 30 +- .../motion/AncientDataMotionStrategy.java | 4 +- .../image/TemplateDataFactoryImpl.java | 11 + .../storage/image/store/TemplateObject.java | 4 +- .../storage/snapshot/SnapshotObject.java | 4 +- .../datastore/ObjectInDataStoreManager.java | 2 +- .../ObjectInDataStoreManagerImpl.java | 2 +- .../storage/db/ObjectInDataStoreVO.java | 2 +- .../datastore/PrimaryDataStoreImpl.java | 2 +- .../storage/volume/VolumeObject.java | 4 +- .../resource/LibvirtComputingResource.java | 190 +-- .../hypervisor/kvm/resource/LibvirtVMDef.java | 6 +- .../kvm/storage/KVMStorageProcessor.java | 879 +++++++++++++ .../kvm/storage/KVMStorageResource.java | 87 ++ .../vmware/resource/VmwareResource.java | 207 +-- ...VmwareSecondaryStorageResourceHandler.java | 10 + .../resource/VmwareStorageProcessor.java | 1144 +++++++++++++++++ .../xen/resource/CitrixResourceBase.java | 84 +- .../xen/resource/XenServer56FP1Resource.java | 21 +- ...ce.java => XenServerStorageProcessor.java} | 621 +++++---- .../CloudStackImageStoreDriverImpl.java | 4 +- .../driver/S3ImageStoreDriverImpl.java | 4 +- .../driver/SampleImageStoreDriverImpl.java | 4 +- .../driver/SwiftImageStoreDriverImpl.java | 4 +- .../CloudStackPrimaryDataStoreDriverImpl.java | 4 +- .../SamplePrimaryDataStoreDriverImpl.java | 2 +- .../SolidfirePrimaryDataStoreDriver.java | 2 +- .../cloud/hypervisor/HypervisorGuruBase.java | 3 +- .../com/cloud/storage/VolumeManagerImpl.java | 70 +- .../storage/download/DownloadListener.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 37 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 52 +- .../cloud/vm/VirtualMachineProfileImpl.java | 11 +- 57 files changed, 3397 insertions(+), 670 deletions(-) rename {engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage => api/src/com/cloud/agent/api/to}/DataObjectType.java (93%) rename {engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage => api/src/com/cloud/agent/api/to}/DataTO.java (90%) create mode 100644 api/src/com/cloud/agent/api/to/DiskTO.java create mode 100644 core/src/com/cloud/storage/resource/StorageProcessor.java create mode 100644 core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java create mode 100644 core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java create mode 100644 engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java create mode 100644 engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java create mode 100644 engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java create mode 100644 engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java create mode 100644 plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java create mode 100644 plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java rename plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/{XenServerStorageResource.java => XenServerStorageProcessor.java} (77%) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectType.java b/api/src/com/cloud/agent/api/to/DataObjectType.java similarity index 93% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectType.java rename to api/src/com/cloud/agent/api/to/DataObjectType.java index b4d1a57c88c..6f7a007e787 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectType.java +++ b/api/src/com/cloud/agent/api/to/DataObjectType.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.engine.subsystem.api.storage; +package com.cloud.agent.api.to; public enum DataObjectType { VOLUME, diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java b/api/src/com/cloud/agent/api/to/DataTO.java similarity index 90% rename from engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java rename to api/src/com/cloud/agent/api/to/DataTO.java index 9e268943865..bd9a16bfc11 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataTO.java +++ b/api/src/com/cloud/agent/api/to/DataTO.java @@ -16,9 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.engine.subsystem.api.storage; - -import com.cloud.agent.api.to.DataStoreTO; +package com.cloud.agent.api.to; public interface DataTO { public DataObjectType getObjectType(); diff --git a/api/src/com/cloud/agent/api/to/DiskTO.java b/api/src/com/cloud/agent/api/to/DiskTO.java new file mode 100644 index 00000000000..7b32f006606 --- /dev/null +++ b/api/src/com/cloud/agent/api/to/DiskTO.java @@ -0,0 +1,60 @@ +/* + * 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.agent.api.to; + +import com.cloud.storage.Volume; + +public class DiskTO { + private DataTO data; + private Long diskSeq; + private Volume.Type type; + public DiskTO() { + + } + + public DiskTO(DataTO data, Long diskSeq, Volume.Type type) { + this.data = data; + this.diskSeq = diskSeq; + this.type = type; + } + + public DataTO getData() { + return data; + } + + public void setData(DataTO data) { + this.data = data; + } + + public Long getDiskSeq() { + return diskSeq; + } + + public void setDiskSeq(Long diskSeq) { + this.diskSeq = diskSeq; + } + + public Volume.Type getType() { + return type; + } + + public void setType(Volume.Type type) { + this.type = type; + } +} diff --git a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java index b84d20a9239..2644c04971b 100644 --- a/api/src/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/com/cloud/agent/api/to/VirtualMachineTO.java @@ -57,7 +57,7 @@ public class VirtualMachineTO { Map params; String uuid; - VolumeTO[] disks; + DiskTO[] disks; NicTO[] nics; public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, String os, boolean enableHA, boolean limitCpuUse, String vncPassword) { @@ -206,11 +206,11 @@ public class VirtualMachineTO { this.bootupScripts = bootupScripts; } - public VolumeTO[] getDisks() { + public DiskTO[] getDisks() { return disks; } - public void setDisks(VolumeTO[] disks) { + public void setDisks(DiskTO[] disks) { this.disks = disks; } diff --git a/api/src/com/cloud/vm/VirtualMachineProfile.java b/api/src/com/cloud/vm/VirtualMachineProfile.java index 33a9171e732..6861372d08d 100644 --- a/api/src/com/cloud/vm/VirtualMachineProfile.java +++ b/api/src/com/cloud/vm/VirtualMachineProfile.java @@ -19,6 +19,8 @@ package com.cloud.vm; import java.util.List; import java.util.Map; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.ServiceOffering; @@ -111,11 +113,11 @@ public interface VirtualMachineProfile { List getNics(); - List getDisks(); + List getDisks(); void addNic(int index, NicProfile nic); - void addDisk(int index, VolumeTO disk); + void addDisk(int index, DiskTO disk); StringBuilder getBootArgsBuilder(); @@ -125,7 +127,7 @@ public interface VirtualMachineProfile { void addNic(NicProfile nic); - void addDisk(VolumeTO disk); + void addDisk(DiskTO disk); VirtualMachine.Type getType(); diff --git a/core/src/com/cloud/serializer/GsonHelper.java b/core/src/com/cloud/serializer/GsonHelper.java index 5656d910959..54b6b171712 100644 --- a/core/src/com/cloud/serializer/GsonHelper.java +++ b/core/src/com/cloud/serializer/GsonHelper.java @@ -20,13 +20,13 @@ package com.cloud.serializer; import java.util.List; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.SecStorageFirewallCfgCommand.PortConfig; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.transport.ArrayTypeAdaptor; import com.cloud.agent.transport.InterfaceTypeAdaptor; import com.cloud.agent.transport.LoggingExclusionStrategy; diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 03e822ebbe7..36b6bbc7ca6 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -46,8 +46,6 @@ import java.util.concurrent.Callable; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DownloadCommand; @@ -97,7 +95,9 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.ssCommand; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/com/cloud/storage/resource/StorageProcessor.java new file mode 100644 index 00000000000..ec965ed424b --- /dev/null +++ b/core/src/com/cloud/storage/resource/StorageProcessor.java @@ -0,0 +1,45 @@ +/* + * 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.storage.resource; + +import org.apache.cloudstack.storage.command.AttachCommand; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.DettachCommand; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; + +public interface StorageProcessor { + public Answer copyTemplateToPrimaryStorage(CopyCommand cmd); + public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd); + public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd); + public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd); + public Answer createTemplateFromVolume(CopyCommand cmd); + public Answer backupSnasphot(CopyCommand cmd); + public Answer attachIso(AttachCommand cmd); + public Answer attachVolume(AttachCommand cmd); + public Answer dettachIso(DettachCommand cmd); + public Answer dettachVolume(DettachCommand cmd); + public Answer createVolume(CreateObjectCommand cmd); + public Answer createSnapshot(CreateObjectCommand cmd); + public Answer deleteVolume(DeleteCommand cmd); +} diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java new file mode 100644 index 00000000000..5ac601e38a9 --- /dev/null +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandler.java @@ -0,0 +1,27 @@ +/* + * 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.storage.resource; + +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; + +import com.cloud.agent.api.Answer; + +public interface StorageSubsystemCommandHandler { + public Answer handleStorageCommands(StorageSubSystemCommand command); +} diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java new file mode 100644 index 00000000000..8f76e93d180 --- /dev/null +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java @@ -0,0 +1,135 @@ +/* + * 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.storage.resource; + +import org.apache.cloudstack.storage.command.AttachCommand; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.DettachCommand; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NfsTO; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Volume; + +public class StorageSubsystemCommandHandlerBase implements StorageSubsystemCommandHandler { + private static final Logger s_logger = Logger.getLogger(StorageSubsystemCommandHandlerBase.class); + private StorageProcessor processor; + public StorageSubsystemCommandHandlerBase(StorageProcessor processor) { + this.processor = processor; + } + @Override + public Answer handleStorageCommands(StorageSubSystemCommand command) { + if (command instanceof CopyCommand) { + return this.execute((CopyCommand)command); + } else if (command instanceof CreateObjectCommand) { + return execute((CreateObjectCommand) command); + } else if (command instanceof DeleteCommand) { + return execute((DeleteCommand)command); + } else if (command instanceof AttachCommand) { + return execute((AttachCommand)command); + } else if (command instanceof DettachCommand) { + return execute((DettachCommand)command); + } + return new Answer((Command)command, false, "not implemented yet"); + } + + protected Answer execute(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + DataStoreTO srcDataStore = srcData.getDataStore(); + DataStoreTO destDataStore = destData.getDataStore(); + + if ((srcData.getObjectType() == DataObjectType.TEMPLATE) && (srcDataStore instanceof NfsTO) && (destData.getDataStore().getRole() == DataStoreRole.Primary)) { + //copy template to primary storage + return processor.copyTemplateToPrimaryStorage(cmd); + } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { + //clone template to a volume + return processor.cloneVolumeFromBaseTemplate(cmd); + } else if (srcData.getObjectType() == DataObjectType.VOLUME && (srcData.getDataStore().getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Image)) { + //copy volume from image cache to primary + return processor.copyVolumeFromImageCacheToPrimary(cmd); + } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { + if (destData.getObjectType() == DataObjectType.VOLUME) { + return processor.copyVolumeFromPrimaryToSecondary(cmd); + } else if (destData.getObjectType() == DataObjectType.TEMPLATE) { + return processor.createTemplateFromVolume(cmd); + } + } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) { + return processor.backupSnasphot(cmd); + } + + return new Answer(cmd, false, "not implemented yet"); + } + + + protected Answer execute(CreateObjectCommand cmd) { + DataTO data = cmd.getData(); + try { + if (data.getObjectType() == DataObjectType.VOLUME) { + return processor.createVolume(cmd); + } else if (data.getObjectType() == DataObjectType.SNAPSHOT) { + return processor.createSnapshot(cmd); + } + return new CreateObjectAnswer("not supported type"); + } catch (Exception e) { + s_logger.debug("Failed to create object: " + data.getObjectType() + ": " + e.toString()); + return new CreateObjectAnswer(e.toString()); + } + } + + protected Answer execute(DeleteCommand cmd) { + DataTO data = cmd.getData(); + Answer answer = null; + if (data.getObjectType() == DataObjectType.VOLUME) { + answer = processor.deleteVolume(cmd); + } else { + answer = new Answer(cmd, false, "unsupported type"); + } + + return answer; + } + + protected Answer execute(AttachCommand cmd) { + DiskTO disk = cmd.getDisk(); + if (disk.getType() == Volume.Type.ISO) { + return processor.attachIso(cmd); + } else { + return processor.attachVolume(cmd); + } + } + + protected Answer execute(DettachCommand cmd) { + DiskTO disk = cmd.getDisk(); + if (disk.getType() == Volume.Type.ISO) { + return processor.dettachIso(cmd); + } else { + return processor.dettachVolume(cmd); + } + } +} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index 8ffed6a1fcd..7610bca59bb 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -19,6 +19,8 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataTO; public interface DataObject { public long getId(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java index cd2dc86cddc..5ed9ab838ad 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; public interface DataStoreDriver { public String grantAccess(DataObject data, EndPoint ep); diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java new file mode 100644 index 00000000000..1ddcd7dce8d --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.command; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DiskTO; + +public class AttachAnswer extends Answer { + private DiskTO disk; + public AttachAnswer() { + super(null); + } + + public AttachAnswer(DiskTO disk) { + this.setDisk(disk); + } + public AttachAnswer(String errMsg) { + super(null, false, errMsg); + } + + public DiskTO getDisk() { + return disk; + } + + public void setDisk(DiskTO disk) { + this.disk = disk; + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java new file mode 100644 index 00000000000..fa205a55eb6 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.command; + + +import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DiskTO; + +public class AttachCommand extends Command implements StorageSubSystemCommand { + private DiskTO disk; + private String vmName; + + public AttachCommand(DiskTO disk, String vmName) { + this.disk = disk; + this.vmName = vmName; + } + + @Override + public boolean executeInSequence() { + // TODO Auto-generated method stub + return false; + } + public DiskTO getDisk() { + return disk; + } + public void setDisk(DiskTO disk) { + this.disk = disk; + } + public String getVmName() { + return vmName; + } + public void setVmName(String vmName) { + this.vmName = vmName; + } + +} diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java index 3612cf98e5c..132832af636 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java @@ -17,9 +17,9 @@ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataTO; public class CopyCmdAnswer extends Answer { private DataTO newData; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index 5bceb03ff93..d512e60d779 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -16,9 +16,9 @@ // under the License. package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; public class CopyCommand extends Command implements StorageSubSystemCommand { private DataTO srcTO; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java index ddd678a0927..2c174e4687f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java @@ -18,9 +18,9 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataTO; public class CreateObjectAnswer extends Answer { private DataTO data; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java index 6a722773592..dfadc2dcea1 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java @@ -18,9 +18,9 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; public class CreateObjectCommand extends Command implements StorageSubSystemCommand { private DataTO data; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 3335848bd86..41af42c58ab 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -18,9 +18,9 @@ */ package org.apache.cloudstack.storage.command; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; public class DeleteCommand extends Command implements StorageSubSystemCommand { private DataTO data; diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java new file mode 100644 index 00000000000..9019e0cfa59 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.command; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DiskTO; + +public class DettachAnswer extends Answer { + private DiskTO disk; + public DettachAnswer() { + super(null); + } + + public DettachAnswer(DiskTO disk) { + this.setDisk(disk); + } + public DettachAnswer(String errMsg) { + super(null, false, errMsg); + } + + public DiskTO getDisk() { + return disk; + } + + public void setDisk(DiskTO disk) { + this.disk = disk; + } +} diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java new file mode 100644 index 00000000000..c435e102120 --- /dev/null +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cloudstack.storage.command; + +import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DiskTO; + +public class DettachCommand extends Command implements StorageSubSystemCommand { + private DiskTO disk; + private String vmName; + + public DettachCommand(DiskTO disk, String vmName) { + this.disk = disk; + this.vmName = vmName; + } + + @Override + public boolean executeInSequence() { + // TODO Auto-generated method stub + return false; + } + public DiskTO getDisk() { + return disk; + } + public void setDisk(DiskTO disk) { + this.disk = disk; + } + public String getVmName() { + return vmName; + } + public void setVmName(String vmName) { + this.vmName = vmName; + } + + +} diff --git a/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index cf9448bd73a..c3ce0e086d4 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -20,17 +20,26 @@ import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.StoragePoolType; public class PrimaryDataStoreTO implements DataStoreTO { private final String uuid; private final String name; private String type; private final long id; + private StoragePoolType poolType; + private String host; + private String path; + private int port; public PrimaryDataStoreTO(PrimaryDataStoreInfo dataStore) { this.uuid = dataStore.getUuid(); this.name = dataStore.getName(); // this.type = dataStore.getType(); this.id = dataStore.getId(); + this.setPoolType(dataStore.getPoolType()); + this.setHost(dataStore.getHostAddress()); + this.setPath(dataStore.getPath()); + this.setPort(dataStore.getPort()); } public long getId() { @@ -53,4 +62,36 @@ public class PrimaryDataStoreTO implements DataStoreTO { public DataStoreRole getRole() { return DataStoreRole.Primary; } + + public StoragePoolType getPoolType() { + return poolType; + } + + public void setPoolType(StoragePoolType poolType) { + this.poolType = poolType; + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java index ed4cbe1756a..a2e336b53e9 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -1,10 +1,10 @@ package org.apache.cloudstack.storage.to; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; public class SnapshotObjectTO implements DataTO { diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index aad5d71536a..14577ef2c00 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -16,13 +16,13 @@ // under the License. package org.apache.cloudstack.storage.to; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.template.VirtualMachineTemplate; @@ -38,6 +38,7 @@ public class TemplateObjectTO implements DataTO { private String displayText; private DataStoreTO imageDataStore; private String name; + private String guestOsType; public TemplateObjectTO() { @@ -151,5 +152,11 @@ public class TemplateObjectTO implements DataTO { this.imageDataStore = imageDataStore; } + public String getGuestOsType() { + return guestOsType; + } + public void setGuestOsType(String guestOsType) { + this.guestOsType = guestOsType; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 3f7a8f1d335..0ae2bc78132 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -16,17 +16,18 @@ // under the License. package org.apache.cloudstack.storage.to; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.storage.Volume; public class VolumeObjectTO implements DataTO { private String uuid; - private VolumeType volumeType; + private Volume.Type volumeType; private DiskFormat diskType; private DataStoreTO dataStore; private String name; @@ -35,6 +36,8 @@ public class VolumeObjectTO implements DataTO { private Long volumeId; private String vmName; private long accountId; + private String chainInfo; + private long id; public VolumeObjectTO() { @@ -52,6 +55,9 @@ public class VolumeObjectTO implements DataTO { this.vmName = volume.getAttachedVmName(); this.size = volume.getSize(); this.setVolumeId(volume.getId()); + this.chainInfo = volume.getChainInfo(); + this.volumeType = volume.getVolumeType(); + this.setId(volume.getId()); } public String getUuid() { @@ -62,7 +68,7 @@ public class VolumeObjectTO implements DataTO { return this.path; } - public VolumeType getVolumeType() { + public Volume.Type getVolumeType() { return this.volumeType; } @@ -130,5 +136,21 @@ public class VolumeObjectTO implements DataTO { this.vmName = vmName; } + public String getChainInfo() { + return chainInfo; + } + + public void setChainInfo(String chainInfo) { + this.chainInfo = chainInfo; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + } 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 index 560c34f0a3f..4e9b02bd7f9 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -26,10 +26,8 @@ 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; @@ -61,7 +59,9 @@ 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.CreatePrivateTemplateAnswer; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java index 6f204266679..09c79b22f98 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java @@ -33,6 +33,7 @@ import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; @@ -89,6 +90,16 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory { } return this.getTemplate(templateId, store); } + + @Override + public TemplateInfo getTemplate(long templateId, long zoneId) { + TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (tmplStore != null) { + DataStore store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), DataStoreRole.Image); + return this.getTemplate(templateId, store); + } + return null; + } @Override diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index daf85681848..12e29e78163 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -24,9 +24,7 @@ import java.util.Map; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; 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.TemplateEvent; @@ -40,6 +38,8 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage.ImageFormat; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index f5800c19bcd..423d8c9f48d 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -22,9 +22,7 @@ import java.util.Date; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -39,6 +37,8 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index ca9f22c7cb4..f49929f2421 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -18,10 +18,10 @@ package org.apache.cloudstack.storage.datastore; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.storage.DataStoreRole; import com.cloud.utils.fsm.NoTransitionException; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index f0b54e1cb3c..4816e51192a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -20,7 +20,6 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; @@ -42,6 +41,7 @@ import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.dao.SnapshotDao; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index 5b69251f161..ecf03913c3e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -30,10 +30,10 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 49bfa653114..55c5b911051 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -25,7 +25,6 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; 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.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; @@ -46,6 +45,7 @@ import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.StoragePoolType; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index be7bd12104d..6754a1dd540 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -21,9 +21,7 @@ import java.util.Date; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -36,6 +34,8 @@ import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Volume; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 706c9ef5670..dd92a3138cf 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -39,11 +39,11 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.HashSet; import java.util.Properties; +import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; @@ -56,11 +56,13 @@ import java.util.regex.Pattern; import javax.ejb.Local; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.utils.qemu.QemuImg; -import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.log4j.Logger; import org.libvirt.Connect; import org.libvirt.Domain; import org.libvirt.DomainInfo; @@ -166,9 +168,13 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; -import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; +import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; @@ -194,11 +200,12 @@ import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InputDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.InterfaceDef.hostNicType; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.SerialDef; -import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.TermPolicy; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.VirtioSerialDef; import com.cloud.hypervisor.kvm.storage.KVMPhysicalDisk; import com.cloud.hypervisor.kvm.storage.KVMStoragePool; import com.cloud.hypervisor.kvm.storage.KVMStoragePoolManager; +import com.cloud.hypervisor.kvm.storage.KVMStorageProcessor; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.RouterPrivateIpStrategy; @@ -212,14 +219,16 @@ import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.storage.Volume; +import com.cloud.storage.resource.StorageSubsystemCommandHandler; +import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; import com.cloud.storage.template.Processor; import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; -import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.TemplateLocation; +import com.cloud.storage.template.TemplateProp; +import com.cloud.utils.FileUtil; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.FileUtil; import com.cloud.utils.PropertiesUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; @@ -345,7 +354,6 @@ ServerResource { protected String _localStoragePath; protected String _localStorageUUID; private final Map _pifs = new HashMap(); - private final Map> hostNetInfo = new HashMap>(); private final Map _vmStats = new ConcurrentHashMap(); protected boolean _disconnected = true; @@ -383,6 +391,8 @@ ServerResource { } protected BridgeType _bridgeType; + + protected StorageSubsystemCommandHandler storageHandler; private String getEndIpFromStartIp(String startIp, int numIps) { String[] tokens = startIp.split("[.]"); @@ -810,6 +820,10 @@ ServerResource { params.put("libvirt.computing.resource", this); configureVifDrivers(params); + + KVMStorageProcessor storageProcessor = new KVMStorageProcessor(this._storagePoolMgr, this); + storageProcessor.configure(name, params); + storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); return true; } @@ -958,11 +972,6 @@ ServerResource { return pif; } - - private String getOvsPif(String bridge) { - String pif = Script.runSimpleBashScript("ovs-vsctl list-ports " + bridge); - return pif; - } private String matchPifFileInDirectory(String bridgeName){ File f = new File("/sys/devices/virtual/net/" + bridgeName + "/brif"); @@ -1203,6 +1212,8 @@ ServerResource { return execute((CheckNetworkCommand) cmd); } else if (cmd instanceof NetworkRulesVmSecondaryIpCommand) { return execute((NetworkRulesVmSecondaryIpCommand) cmd); + } else if (cmd instanceof StorageSubSystemCommand) { + return this.storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else { s_logger.warn("Unsupported command "); return Answer.createUnsupportedCommandAnswer(cmd); @@ -1496,8 +1507,6 @@ ServerResource { vol.getPoolType(), vol.getPoolUuid()); pool.deletePhysicalDisk(vol.getPath()); - String vmName = cmd.getVmName(); - String poolPath = pool.getLocalPath(); return new Answer(cmd, true, "Success"); } catch (CloudRuntimeException e) { s_logger.debug("Failed to delete volume: " + e.toString()); @@ -1606,7 +1615,6 @@ ServerResource { try { conn = LibvirtConnection.getConnectionByVmName(routerName); - Domain vm = getDomain(conn, routerName); List pluggedNics = getInterfaces(conn, routerName); InterfaceDef routerNic = null; @@ -1621,7 +1629,6 @@ ServerResource { return new SetupGuestNetworkAnswer(cmd, false, "Can not find nic with mac " + nic.getMac() + " for VM " + routerName); } - String args = "vpc_guestnw.sh " + routerIP + " -C"; String dev = "eth" + nic.getDeviceId(); String netmask = NetUtils.getSubNet(routerGIP, nic.getNetmask()); String result = _virtRouterResource.assignGuestNetwork(dev, routerIP, @@ -1640,14 +1647,10 @@ ServerResource { private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) { String[] results = new String[cmd.getRules().length]; - String callResult; - Connect conn; - String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME); + String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP); try { - conn = LibvirtConnection.getConnectionByVmName(routerName); - Domain vm = getDomain(conn, routerName); String [][] rules = cmd.generateFwRules(); String[] aclRules = rules[0]; NicTO nic = cmd.getNic(); @@ -1671,7 +1674,7 @@ ServerResource { } return new SetNetworkACLAnswer(cmd, true, results); - } catch (LibvirtException e) { + } catch (Exception e) { String msg = "SetNetworkACL failed due to " + e.toString(); s_logger.error(msg, e); return new SetNetworkACLAnswer(cmd, false, results); @@ -1686,7 +1689,6 @@ ServerResource { try { conn = LibvirtConnection.getConnectionByVmName(routerName); - Domain vm = getDomain(conn, routerName); Integer devNum = 0; String pubVlan = pubIP.getVlanId(); List pluggedNics = getInterfaces(conn, routerName); @@ -1733,7 +1735,6 @@ ServerResource { try { conn = LibvirtConnection.getConnectionByVmName(routerName); IpAddressTO[] ips = cmd.getIpAddresses(); - Domain vm = getDomain(conn, routerName); Integer devNum = 0; Map vlanToNicNum = new HashMap(); List pluggedNics = getInterfaces(conn, routerName); @@ -1919,7 +1920,6 @@ ServerResource { Long volumeId = cmd.getVolumeId(); String secondaryStoragePoolUrl = cmd.getSecondaryStorageUrl(); String snapshotName = cmd.getSnapshotName(); - String snapshotPath = cmd.getVolumePath(); String snapshotDestPath = null; String snapshotRelPath = null; String vmName = cmd.getVmName(); @@ -2194,7 +2194,6 @@ ServerResource { KVMStoragePool secondaryStorage = null; KVMStoragePool primary = null; try { - Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); String templateFolder = cmd.getAccountId() + File.separator + cmd.getTemplateId() + File.separator; String templateInstallFolder = "/template/tmpl/" + templateFolder; @@ -2290,10 +2289,6 @@ ServerResource { templateInstallFolder + cmd.getUniqueName() + ".qcow2", info.virtualSize, info.size, cmd.getUniqueName(), ImageFormat.QCOW2); - } catch (LibvirtException e) { - s_logger.debug("Failed to get secondary storage pool: " - + e.toString()); - return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); } catch (InternalErrorException e) { return new CreatePrivateTemplateAnswer(cmd, false, e.toString()); } catch (IOException e) { @@ -2372,7 +2367,6 @@ ServerResource { } protected Answer execute(ModifyStoragePoolCommand cmd) { - String poolType = cmd.getPool().getType().toString(); KVMStoragePool storagepool = _storagePoolMgr.createStoragePool(cmd .getPool().getUuid(), cmd.getPool().getHost(), cmd.getPool().getPort(), cmd.getPool().getPath(), @@ -2700,8 +2694,8 @@ ServerResource { } /* setup disks, e.g for iso */ - VolumeTO[] volumes = vm.getDisks(); - for (VolumeTO volume : volumes) { + DiskTO[] volumes = vm.getDisks(); + for (DiskTO volume : volumes) { if (volume.getType() == Volume.Type.ISO) { getVolumePath(conn, volume); } @@ -3279,10 +3273,14 @@ ServerResource { } } - private String getVolumePath(Connect conn, VolumeTO volume) + private String getVolumePath(Connect conn, DiskTO volume) throws LibvirtException, URISyntaxException { - if (volume.getType() == Volume.Type.ISO && volume.getPath() != null) { - String isoPath = volume.getPath(); + DataTO data = volume.getData(); + DataStoreTO store = data.getDataStore(); + + if (volume.getType() == Volume.Type.ISO && data.getPath() != null) { + NfsTO nfsStore = (NfsTO)store; + String isoPath = nfsStore.getUrl() + File.separator + data.getPath(); int index = isoPath.lastIndexOf("/"); String path = isoPath.substring(0, index); String name = isoPath.substring(index + 1); @@ -3291,26 +3289,28 @@ ServerResource { KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); return isoVol.getPath(); } else { - return volume.getPath(); + return data.getPath(); } } protected void createVbd(Connect conn, VirtualMachineTO vmSpec, String vmName, LibvirtVMDef vm) throws InternalErrorException, LibvirtException, URISyntaxException { - List disks = Arrays.asList(vmSpec.getDisks()); - Collections.sort(disks, new Comparator() { + List disks = Arrays.asList(vmSpec.getDisks()); + Collections.sort(disks, new Comparator() { @Override - public int compare(VolumeTO arg0, VolumeTO arg1) { - return arg0.getDeviceId() > arg1.getDeviceId() ? 1 : -1; + public int compare(DiskTO arg0, DiskTO arg1) { + return arg0.getDiskSeq() > arg1.getDiskSeq() ? 1 : -1; } }); - for (VolumeTO volume : disks) { + for (DiskTO volume : disks) { KVMPhysicalDisk physicalDisk = null; KVMStoragePool pool = null; - if (volume.getType() == Volume.Type.ISO && volume.getPath() != null) { - String volPath = volume.getPath(); + DataTO data = volume.getData(); + if (volume.getType() == Volume.Type.ISO && data.getPath() != null) { + NfsTO nfsStore = (NfsTO)data.getDataStore(); + String volPath = nfsStore.getUrl() + File.separator + data.getPath(); int index = volPath.lastIndexOf("/"); String volDir = volPath.substring(0, index); String volName = volPath.substring(index + 1); @@ -3318,10 +3318,11 @@ ServerResource { getStoragePoolByURI(volDir); physicalDisk = secondaryStorage.getPhysicalDisk(volName); } else if (volume.getType() != Volume.Type.ISO) { + PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore(); pool = _storagePoolMgr.getStoragePool( - volume.getPoolType(), - volume.getPoolUuid()); - physicalDisk = pool.getPhysicalDisk(volume.getPath()); + store.getPoolType(), + store.getUuid()); + physicalDisk = pool.getPhysicalDisk(data.getPath()); } String volPath = null; @@ -3339,7 +3340,7 @@ ServerResource { disk.defISODisk(volPath); } } else { - int devId = (int) volume.getDeviceId(); + int devId = volume.getDiskSeq().intValue(); if (pool.getType() == StoragePoolType.RBD) { /* @@ -3379,12 +3380,14 @@ ServerResource { // For LXC, find and add the root filesystem if (HypervisorType.LXC.toString().toLowerCase().equals(vm.getHvsType())) { - for (VolumeTO volume : disks) { + for (DiskTO volume : disks) { if (volume.getType() == Volume.Type.ROOT) { + DataTO data = volume.getData(); + PrimaryDataStoreTO store = (PrimaryDataStoreTO)data.getDataStore(); KVMStoragePool pool = _storagePoolMgr.getStoragePool( - volume.getPoolType(), - volume.getPoolUuid()); - KVMPhysicalDisk physicalDisk = pool.getPhysicalDisk(volume.getPath()); + store.getPoolType(), + store.getUuid()); + KVMPhysicalDisk physicalDisk = pool.getPhysicalDisk(data.getPath()); FilesystemDef rootFs = new FilesystemDef(physicalDisk.getPath(), "/"); vm.getDevices().addDevice(rootFs); break; @@ -3394,16 +3397,6 @@ ServerResource { } - private VolumeTO getVolume(VirtualMachineTO vmSpec, Volume.Type type) { - VolumeTO volumes[] = vmSpec.getDisks(); - for (VolumeTO volume : volumes) { - if (volume.getType() == type) { - return volume; - } - } - return null; - } - private void createVif(LibvirtVMDef vm, NicTO nic) throws InternalErrorException, LibvirtException { vm.getDevices().addDevice( @@ -3432,7 +3425,7 @@ ServerResource { return new CheckSshAnswer(cmd); } - private boolean cleanupDisk(Connect conn, DiskDef disk) { + public boolean cleanupDisk(Connect conn, DiskDef disk) { // need to umount secondary storage String path = disk.getDiskPath(); String poolUuid = null; @@ -4237,28 +4230,6 @@ ServerResource { return parser.getEmulator(); } - private String getGuestType(Connect conn, String vmName) { - LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); - Domain dm = null; - try { - dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName - .getBytes())); - String xmlDesc = dm.getXMLDesc(0); - parser.parseDomainXML(xmlDesc); - return parser.getDescription(); - } catch (LibvirtException e) { - s_logger.trace("Ignoring libvirt error.", e); - return null; - } finally { - try { - if (dm != null) { - dm.free(); - } - } catch (LibvirtException l) { - s_logger.trace("Ignoring libvirt error.", l); - } - } - } boolean isGuestPVEnabled(String guestOS) { if (guestOS == null) { @@ -4296,14 +4267,6 @@ ServerResource { } } - private InterfaceDef.nicModel getGuestNicModel(String guestOSType) { - if (isGuestPVEnabled(guestOSType)) { - return InterfaceDef.nicModel.VIRTIO; - } else { - return InterfaceDef.nicModel.E1000; - } - } - private DiskDef.diskBus getGuestDiskModel(String guestOSType) { if (isGuestPVEnabled(guestOSType)) { return DiskDef.diskBus.VIRTIO; @@ -4337,7 +4300,7 @@ ServerResource { } } - private Domain getDomain(Connect conn, String vmName) + public Domain getDomain(Connect conn, String vmName) throws LibvirtException { return conn .domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes())); @@ -4366,7 +4329,7 @@ ServerResource { } } - protected List getDisks(Connect conn, String vmName) { + public List getDisks(Connect conn, String vmName) { LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); Domain dm = null; try { @@ -4396,38 +4359,7 @@ ServerResource { return command.execute(); } - private String executeBashScript(String script, OutputInterpreter parser) { - Script command = new Script("/bin/bash", _timeout, s_logger); - command.add("-c"); - command.add(script); - return command.execute(parser); - } - private void deletExitingLinkLocalRoutTable(String linkLocalBr) { - Script command = new Script("/bin/bash", _timeout); - command.add("-c"); - command.add("ip route | grep " + NetUtils.getLinkLocalCIDR()); - OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); - String result = command.execute(parser); - boolean foundLinkLocalBr = false; - if (result == null && parser.getLines() != null) { - String[] lines = parser.getLines().split("\\n"); - for (String line : lines) { - String[] tokens = line.split(" "); - if (!tokens[2].equalsIgnoreCase(linkLocalBr)) { - Script.runSimpleBashScript("ip route del " - + NetUtils.getLinkLocalCIDR()); - } else { - foundLinkLocalBr = true; - } - } - } - if (!foundLinkLocalBr) { - Script.runSimpleBashScript("ip route add " - + NetUtils.getLinkLocalCIDR() + " dev " + linkLocalBr - + " src " + NetUtils.getLinkLocalGateway()); - } - } private class vmStats { long _usedTime; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java index 9cddb2e4323..345b4e8e71c 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java @@ -354,7 +354,7 @@ public class LibvirtVMDef { } public static class DiskDef { - enum deviceType { + public enum deviceType { FLOPPY("floppy"), DISK("disk"), CDROM("cdrom"); String _type; @@ -396,7 +396,7 @@ public class LibvirtVMDef { } } - enum diskBus { + public enum diskBus { IDE("ide"), SCSI("scsi"), VIRTIO("virtio"), XEN("xen"), USB("usb"), UML( "uml"), FDC("fdc"); String _bus; @@ -411,7 +411,7 @@ public class LibvirtVMDef { } } - enum diskFmtType { + public enum diskFmtType { RAW("raw"), QCOW2("qcow2"); String _fmtType; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java new file mode 100644 index 00000000000..c3fc0ec22a4 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -0,0 +1,879 @@ +/* + * 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.kvm.storage; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URISyntaxException; +import java.text.DateFormat; +import java.text.MessageFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.naming.ConfigurationException; + +import org.apache.cloudstack.storage.command.AttachAnswer; +import org.apache.cloudstack.storage.command.AttachCommand; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.DettachAnswer; +import org.apache.cloudstack.storage.command.DettachCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImgException; +import org.apache.cloudstack.utils.qemu.QemuImgFile; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; +import org.apache.log4j.Logger; +import org.libvirt.Connect; +import org.libvirt.Domain; +import org.libvirt.DomainInfo; +import org.libvirt.DomainSnapshot; +import org.libvirt.LibvirtException; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.AttachVolumeAnswer; +import com.cloud.agent.api.BackupSnapshotAnswer; +import com.cloud.agent.api.ManageSnapshotAnswer; +import com.cloud.agent.api.ManageSnapshotCommand; +import com.cloud.agent.api.storage.CreateAnswer; +import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NfsTO; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.exception.InternalErrorException; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; +import com.cloud.hypervisor.kvm.resource.LibvirtConnection; +import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser; +import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; +import com.cloud.storage.JavaStorageLayer; +import com.cloud.storage.StorageLayer; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.resource.StorageProcessor; +import com.cloud.storage.template.Processor; +import com.cloud.storage.template.QCOW2Processor; +import com.cloud.storage.template.TemplateLocation; +import com.cloud.storage.template.Processor.FormatInfo; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; +import com.cloud.vm.DiskProfile; + +public class KVMStorageProcessor implements StorageProcessor { + private static final Logger s_logger = Logger.getLogger(KVMStorageProcessor.class); + private KVMStoragePoolManager storagePoolMgr; + private LibvirtComputingResource resource; + private StorageLayer storageLayer; + private String _createTmplPath; + private String _manageSnapshotPath; + private int _cmdsTimeout; + public KVMStorageProcessor(KVMStoragePoolManager storagePoolMgr, LibvirtComputingResource resource) { + this.storagePoolMgr = storagePoolMgr; + this.resource = resource; + } + + protected String getDefaultStorageScriptsDir() { + return "scripts/storage/qcow2"; + } + + public boolean configure(String name, Map params) + throws ConfigurationException { + storageLayer = new JavaStorageLayer(); + storageLayer.configure("StorageLayer", params); + + String storageScriptsDir = (String) params.get("storage.scripts.dir"); + if (storageScriptsDir == null) { + storageScriptsDir = getDefaultStorageScriptsDir(); + } + + _createTmplPath = Script + .findScript(storageScriptsDir, "createtmplt.sh"); + if (_createTmplPath == null) { + throw new ConfigurationException( + "Unable to find the createtmplt.sh"); + } + + _manageSnapshotPath = Script.findScript(storageScriptsDir, + "managesnapshot.sh"); + if (_manageSnapshotPath == null) { + throw new ConfigurationException( + "Unable to find the managesnapshot.sh"); + } + + String value = (String) params.get("cmds.timeout"); + _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; + return true; + } + + @Override + public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + TemplateObjectTO template = (TemplateObjectTO)srcData; + DataStoreTO imageStore = template.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO)destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + + NfsTO nfsImageStore = (NfsTO)imageStore; + String tmplturl = nfsImageStore.getUrl() + File.separator + template.getPath(); + int index = tmplturl.lastIndexOf("/"); + String mountpoint = tmplturl.substring(0, index); + String tmpltname = null; + if (index < tmplturl.length() - 1) { + tmpltname = tmplturl.substring(index + 1); + } + + KVMPhysicalDisk tmplVol = null; + KVMStoragePool secondaryPool = null; + try { + secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint); + + /* Get template vol */ + if (tmpltname == null) { + secondaryPool.refresh(); + List disks = secondaryPool.listPhysicalDisks(); + if (disks == null || disks.isEmpty()) { + return new PrimaryStorageDownloadAnswer( + "Failed to get volumes from pool: " + + secondaryPool.getUuid()); + } + for (KVMPhysicalDisk disk : disks) { + if (disk.getName().endsWith("qcow2")) { + tmplVol = disk; + break; + } + } + if (tmplVol == null) { + return new PrimaryStorageDownloadAnswer( + "Failed to get template from pool: " + + secondaryPool.getUuid()); + } + } else { + tmplVol = secondaryPool.getPhysicalDisk(tmpltname); + } + + /* Copy volume to primary storage */ + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + + KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk( + tmplVol, UUID.randomUUID().toString(), primaryPool); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(primaryVol.getName()); + newVol.setSize(primaryVol.getSize()); + return new CopyCmdAnswer(newVol); + } catch (CloudRuntimeException e) { + return new CopyCmdAnswer(e.toString()); + } finally { + if (secondaryPool != null) { + secondaryPool.delete(); + } + } + } + + // this is much like PrimaryStorageDownloadCommand, but keeping it separate + private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool) { + int index = templateUrl.lastIndexOf("/"); + String mountpoint = templateUrl.substring(0, index); + String templateName = null; + if (index < templateUrl.length() - 1) { + templateName = templateUrl.substring(index + 1); + } + + KVMPhysicalDisk templateVol = null; + KVMStoragePool secondaryPool = null; + try { + secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint); + /* Get template vol */ + if (templateName == null) { + secondaryPool.refresh(); + List disks = secondaryPool.listPhysicalDisks(); + if (disks == null || disks.isEmpty()) { + s_logger.error("Failed to get volumes from pool: " + secondaryPool.getUuid()); + return null; + } + for (KVMPhysicalDisk disk : disks) { + if (disk.getName().endsWith("qcow2")) { + templateVol = disk; + break; + } + } + if (templateVol == null) { + s_logger.error("Failed to get template from pool: " + secondaryPool.getUuid()); + return null; + } + } else { + templateVol = secondaryPool.getPhysicalDisk(templateName); + } + + /* Copy volume to primary storage */ + + KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool); + return primaryVol; + } catch (CloudRuntimeException e) { + s_logger.error("Failed to download template to primary storage",e); + return null; + } finally { + if (secondaryPool != null) { + secondaryPool.delete(); + } + } + } + + @Override + public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + TemplateObjectTO template = (TemplateObjectTO)srcData; + DataStoreTO imageStore = template.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO)destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + KVMPhysicalDisk BaseVol = null; + KVMStoragePool primaryPool = null; + KVMPhysicalDisk vol = null; + + try { + primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), + primaryStore.getUuid()); + + String templatePath = null; + if (imageStore instanceof NfsTO) { + NfsTO nfsImageStore = (NfsTO)imageStore; + templatePath = nfsImageStore.getUrl(); + } else { + s_logger.debug("Failed to create volume: "); + return new CopyCmdAnswer("Unsupported protocol"); + } + + if(primaryPool.getType() == StoragePoolType.CLVM) { + vol = templateToPrimaryDownload(templatePath, primaryPool); + } else { + BaseVol = primaryPool.getPhysicalDisk(templatePath); + vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID + .randomUUID().toString(), primaryPool); + } + if (vol == null) { + return new CopyCmdAnswer( + " Can't create storage volume on storage pool"); + } + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(vol.getName()); + newVol.setSize(vol.getSize()); + + return new CopyCmdAnswer(newVol); + } catch (CloudRuntimeException e) { + s_logger.debug("Failed to create volume: " + e.toString()); + return new CopyCmdAnswer(e.toString()); + } + } + + @Override + public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { + return null; + } + + @Override + public Answer createTemplateFromVolume(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); + TemplateObjectTO template = (TemplateObjectTO)srcData; + DataStoreTO imageStore = template.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO)destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + NfsTO nfsImageStore = (NfsTO)imageStore; + + KVMStoragePool secondaryStorage = null; + KVMStoragePool primary = null; + try { + String templateFolder = template.getPath(); + + secondaryStorage = storagePoolMgr.getStoragePoolByURI( + nfsImageStore.getUrl()); + + try { + primary = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + } catch (CloudRuntimeException e) { + if (e.getMessage().contains("not found")) { + primary = storagePoolMgr.createStoragePool(primaryStore.getUuid(), + primaryStore.getHost(), primaryStore.getPort(), + primaryStore.getPath(), null, + primaryStore.getPoolType()); + } else { + return new CopyCmdAnswer(e.getMessage()); + } + } + + KVMPhysicalDisk disk = primary.getPhysicalDisk(volume.getPath()); + String tmpltPath = secondaryStorage.getLocalPath() + File.separator + + templateFolder; + this.storageLayer.mkdirs(tmpltPath); + String templateName = UUID.randomUUID().toString(); + + if (primary.getType() != StoragePoolType.RBD) { + Script command = new Script(_createTmplPath, wait, s_logger); + command.add("-f", disk.getPath()); + command.add("-t", tmpltPath); + command.add("-n", templateName + ".qcow2"); + + String result = command.execute(); + + if (result != null) { + s_logger.debug("failed to create template: " + result); + return new CopyCmdAnswer(result); + } + } else { + s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + templateName); + + QemuImgFile srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), + primary.getSourcePort(), + primary.getAuthUserName(), + primary.getAuthSecret(), + disk.getPath())); + srcFile.setFormat(PhysicalDiskFormat.RAW); + + QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + templateName + ".qcow2"); + destFile.setFormat(PhysicalDiskFormat.QCOW2); + + QemuImg q = new QemuImg(); + try { + q.convert(srcFile, destFile); + } catch (QemuImgException e) { + s_logger.error("Failed to create new template while converting " + + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage()); + } + + File templateProp = new File(tmpltPath + "/template.properties"); + if (!templateProp.exists()) { + templateProp.createNewFile(); + } + + String templateContent = "filename=" + templateName + ".qcow2" + System.getProperty("line.separator"); + + DateFormat dateFormat = new SimpleDateFormat("MM_dd_yyyy"); + Date date = new Date(); + templateContent += "snapshot.name=" + dateFormat.format(date) + System.getProperty("line.separator"); + + FileOutputStream templFo = new FileOutputStream(templateProp); + templFo.write(templateContent.getBytes()); + templFo.flush(); + templFo.close(); + } + + Map params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, this.storageLayer); + Processor qcow2Processor = new QCOW2Processor(); + + qcow2Processor.configure("QCOW2 Processor", params); + + FormatInfo info = qcow2Processor.process(tmpltPath, null, + templateName); + + TemplateLocation loc = new TemplateLocation(this.storageLayer, tmpltPath); + loc.create(1, true, templateName); + loc.addFormat(info); + loc.save(); + + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(templateFolder + templateName + ".qcow2"); + return new CopyCmdAnswer(newTemplate); + } catch (Exception e) { + s_logger.debug("Failed to create template from volume: " + e.toString()); + return new CopyCmdAnswer(e.toString()); + } finally { + if (secondaryStorage != null) { + secondaryStorage.delete(); + } + } + } + + @Override + public Answer backupSnasphot(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); + SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshot.getDataStore(); + SnapshotObjectTO destSnapshot = (SnapshotObjectTO)destData; + DataStoreTO imageStore = destData.getDataStore(); + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + NfsTO nfsImageStore = (NfsTO)imageStore; + + String secondaryStoragePoolUrl = nfsImageStore.getUrl(); + //NOTE: snapshot name is encoded in snapshot path + int index = snapshot.getPath().lastIndexOf("/"); + + String snapshotName = snapshot.getPath().substring(index + 1); + String volumePath = snapshot.getVolume().getPath(); + String snapshotDestPath = null; + String snapshotRelPath = null; + String vmName = snapshot.getVmName(); + KVMStoragePool secondaryStoragePool = null; + try { + Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + + secondaryStoragePool = storagePoolMgr.getStoragePoolByURI( + secondaryStoragePoolUrl); + + String ssPmountPath = secondaryStoragePool.getLocalPath(); + snapshotRelPath = destSnapshot.getPath(); + + snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath; + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(volumePath); + Script command = new Script(_manageSnapshotPath, _cmdsTimeout, + s_logger); + command.add("-b", snapshotDisk.getPath()); + command.add("-n", snapshotName); + command.add("-p", snapshotDestPath); + command.add("-t", snapshotName); + String result = command.execute(); + if (result != null) { + s_logger.debug("Failed to backup snaptshot: " + result); + return new CopyCmdAnswer(result); + } + /* Delete the snapshot on primary */ + + DomainInfo.DomainState state = null; + Domain vm = null; + if (vmName != null) { + try { + vm = this.resource.getDomain(conn, vmName); + state = vm.getInfo().state; + } catch (LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + } + + KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING + && !primaryStorage.isExternalSnapshot()) { + DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); + snap.delete(0); + + /* + * libvirt on RHEL6 doesn't handle resume event emitted from + * qemu + */ + vm = this.resource.getDomain(conn, vmName); + state = vm.getInfo().state; + if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) { + vm.resume(); + } + } else { + command = new Script(_manageSnapshotPath, _cmdsTimeout, + s_logger); + command.add("-d", snapshotDisk.getPath()); + command.add("-n", snapshotName); + result = command.execute(); + if (result != null) { + s_logger.debug("Failed to backup snapshot: " + result); + return new CopyCmdAnswer( + "Failed to backup snapshot: " + result); + } + } + + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + newSnapshot.setPath(snapshotRelPath + + File.separator + snapshotName); + return new CopyCmdAnswer(newSnapshot); + } catch (LibvirtException e) { + s_logger.debug("Failed to backup snapshot: " + e.toString()); + return new CopyCmdAnswer(e.toString()); + } catch (CloudRuntimeException e) { + s_logger.debug("Failed to backup snapshot: " + e.toString()); + return new CopyCmdAnswer(e.toString()); + } finally { + if (secondaryStoragePool != null) { + secondaryStoragePool.delete(); + } + } + } + + protected synchronized String attachOrDetachISO(Connect conn, + String vmName, String isoPath, boolean isAttach) + throws LibvirtException, URISyntaxException, InternalErrorException { + String isoXml = null; + if (isoPath != null && isAttach) { + int index = isoPath.lastIndexOf("/"); + String path = isoPath.substring(0, index); + String name = isoPath.substring(index + 1); + KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI( + path); + KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); + isoPath = isoVol.getPath(); + + DiskDef iso = new DiskDef(); + iso.defISODisk(isoPath); + isoXml = iso.toString(); + } else { + DiskDef iso = new DiskDef(); + iso.defISODisk(null); + isoXml = iso.toString(); + } + + List disks = this.resource.getDisks(conn, vmName); + String result = attachOrDetachDevice(conn, true, vmName, isoXml); + if (result == null && !isAttach) { + for (DiskDef disk : disks) { + if (disk.getDeviceType() == DiskDef.deviceType.CDROM) { + this.resource.cleanupDisk(conn, disk); + } + } + + } + return result; + } + @Override + public Answer attachIso(AttachCommand cmd) { + DiskTO disk = cmd.getDisk(); + TemplateObjectTO isoTO = (TemplateObjectTO)disk.getData(); + DataStoreTO store = isoTO.getDataStore(); + if (!(store instanceof NfsTO)) { + return new AttachAnswer("unsupported protocol"); + } + NfsTO nfsStore = (NfsTO)store; + try { + Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + attachOrDetachISO(conn, cmd.getVmName(), nfsStore.getUrl() + File.separator + isoTO.getPath(), + true); + } catch (LibvirtException e) { + return new Answer(cmd, false, e.toString()); + } catch (URISyntaxException e) { + return new Answer(cmd, false, e.toString()); + } catch (InternalErrorException e) { + return new Answer(cmd, false, e.toString()); + } + + return new Answer(cmd); + } + + protected synchronized String attachOrDetachDevice(Connect conn, + boolean attach, String vmName, String xml) throws LibvirtException, + InternalErrorException { + Domain dm = null; + try { + dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes((vmName + .getBytes()))); + + if (attach) { + s_logger.debug("Attaching device: " + xml); + dm.attachDevice(xml); + } else { + s_logger.debug("Detaching device: " + xml); + dm.detachDevice(xml); + } + } catch (LibvirtException e) { + if (attach) { + s_logger.warn("Failed to attach device to " + vmName + ": " + + e.getMessage()); + } else { + s_logger.warn("Failed to detach device from " + vmName + ": " + + e.getMessage()); + } + throw e; + } finally { + if (dm != null) { + try { + dm.free(); + } catch (LibvirtException l) { + s_logger.trace("Ignoring libvirt error.", l); + } + } + } + + return null; + } + + protected synchronized String attachOrDetachDisk(Connect conn, + boolean attach, String vmName, KVMPhysicalDisk attachingDisk, + int devId) throws LibvirtException, InternalErrorException { + List disks = null; + Domain dm = null; + DiskDef diskdef = null; + try { + if (!attach) { + dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName + .getBytes())); + LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); + String xml = dm.getXMLDesc(0); + parser.parseDomainXML(xml); + disks = parser.getDisks(); + + for (DiskDef disk : disks) { + String file = disk.getDiskPath(); + if (file != null + && file.equalsIgnoreCase(attachingDisk.getPath())) { + diskdef = disk; + break; + } + } + if (diskdef == null) { + throw new InternalErrorException("disk: " + + attachingDisk.getPath() + + " is not attached before"); + } + } else { + diskdef = new DiskDef(); + if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) { + diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, + DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2); + } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) { + diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, + DiskDef.diskBus.VIRTIO); + } + } + + String xml = diskdef.toString(); + return attachOrDetachDevice(conn, attach, vmName, xml); + } finally { + if (dm != null) { + dm.free(); + } + } + } + + @Override + public Answer attachVolume(AttachCommand cmd) { + DiskTO disk = cmd.getDisk(); + VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); + String vmName = vol.getVmName(); + try { + Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + KVMStoragePool primary = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + + KVMPhysicalDisk phyDisk = primary.getPhysicalDisk(vol.getPath()); + attachOrDetachDisk(conn, true, vmName, phyDisk, + disk.getDiskSeq().intValue()); + + return new AttachAnswer(disk); + } catch (LibvirtException e) { + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + return new AttachAnswer(e.toString()); + } catch (InternalErrorException e) { + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + return new AttachAnswer(e.toString()); + } + + + } + + @Override + public Answer dettachIso(DettachCommand cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Answer dettachVolume(DettachCommand cmd) { + DiskTO disk = cmd.getDisk(); + VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); + String vmName = vol.getVmName(); + try { + Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + KVMStoragePool primary = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + + KVMPhysicalDisk phyDisk = primary.getPhysicalDisk(vol.getPath()); + attachOrDetachDisk(conn, false, vmName, phyDisk, + disk.getDiskSeq().intValue()); + + return new DettachAnswer(disk); + } catch (LibvirtException e) { + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + return new DettachAnswer(e.toString()); + } catch (InternalErrorException e) { + s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); + return new DettachAnswer(e.toString()); + } + } + + @Override + public Answer createVolume(CreateObjectCommand cmd) { + VolumeObjectTO volume = (VolumeObjectTO)cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + + KVMStoragePool primaryPool = null; + KVMPhysicalDisk vol = null; + long disksize; + try { + primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), + primaryStore.getUuid()); + disksize = volume.getSize(); + + vol = primaryPool.createPhysicalDisk(UUID.randomUUID() + .toString(), disksize); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(vol.getName()); + + return new CreateObjectAnswer(newVol); + } catch (Exception e) { + s_logger.debug("Failed to create volume: " + e.toString()); + return new CreateObjectAnswer(e.toString()); + } + } + + protected static MessageFormat SnapshotXML = new MessageFormat( + " " + " {0}" + " " + + " {1}" + " " + + " "); + + @Override + public Answer createSnapshot(CreateObjectCommand cmd) { + VolumeObjectTO volume = (VolumeObjectTO)cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + String snapshotName = UUID.randomUUID().toString(); + String vmName = volume.getVmName(); + try { + Connect conn = LibvirtConnection.getConnectionByVmName(vmName); + DomainInfo.DomainState state = null; + Domain vm = null; + if (vmName != null) { + try { + vm = this.resource.getDomain(conn, vmName); + state = vm.getInfo().state; + } catch (LibvirtException e) { + s_logger.trace("Ignoring libvirt error.", e); + } + } + + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + + if (primaryPool.getType() == StoragePoolType.RBD) { + s_logger.debug("Snapshots are not supported on RBD volumes"); + return new CreateObjectAnswer( + "Snapshots are not supported on RBD volumes"); + } + + KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(volume.getPath()); + if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING + && !primaryPool.isExternalSnapshot()) { + String vmUuid = vm.getUUIDString(); + Object[] args = new Object[] { snapshotName, vmUuid }; + String snapshot = SnapshotXML.format(args); + s_logger.debug(snapshot); + + vm.snapshotCreateXML(snapshot); + /* + * libvirt on RHEL6 doesn't handle resume event emitted from + * qemu + */ + vm = this.resource.getDomain(conn, vmName); + state = vm.getInfo().state; + if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) { + vm.resume(); + } + } else { + + /* VM is not running, create a snapshot by ourself */ + final Script command = new Script(_manageSnapshotPath, + this._cmdsTimeout, s_logger); + command.add("-c", disk.getPath()); + command.add("-n", snapshotName); + String result = command.execute(); + if (result != null) { + s_logger.debug("Failed to manage snapshot: " + result); + return new CreateObjectAnswer( + "Failed to manage snapshot: " + result); + } + } + + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + //NOTE: sort of hack, we'd better just put snapshtoName + newSnapshot.setPath(disk.getPath() + File.separator + snapshotName); + return new CreateObjectAnswer(newSnapshot); + } catch (LibvirtException e) { + s_logger.debug("Failed to manage snapshot: " + e.toString()); + return new CreateObjectAnswer( + "Failed to manage snapshot: " + e.toString()); + } + } + + @Override + public Answer deleteVolume(DeleteCommand cmd) { + VolumeObjectTO vol = (VolumeObjectTO)cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); + try { + KVMStoragePool pool = storagePoolMgr.getStoragePool( + primaryStore.getPoolType(), + primaryStore.getUuid()); + try { + pool.getPhysicalDisk(vol.getPath()); + } catch(Exception e) { + s_logger.debug("can't find volume: " + vol.getPath() + ", return true"); + return new Answer(null); + } + pool.deletePhysicalDisk(vol.getPath()); + return new Answer(null); + } catch (CloudRuntimeException e) { + s_logger.debug("Failed to delete volume: " + e.toString()); + return new Answer(null, false, e.toString()); + } + } + +} diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java new file mode 100644 index 00000000000..52e142e4e13 --- /dev/null +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageResource.java @@ -0,0 +1,87 @@ +/* + * 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.kvm.storage; + +import org.apache.cloudstack.storage.command.AttachCommand; +import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.DettachCommand; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; + +public class KVMStorageResource { + private LibvirtComputingResource resource; + public KVMStorageResource(LibvirtComputingResource resource) { + this.resource = resource; + } + + public Answer handleStorageCommands(StorageSubSystemCommand command) { + if (command instanceof CopyCommand) { + return this.execute((CopyCommand)command); + } else if (command instanceof AttachPrimaryDataStoreCmd) { + return this.execute((AttachPrimaryDataStoreCmd)command); + } else if (command instanceof CreatePrimaryDataStoreCmd) { + return execute((CreatePrimaryDataStoreCmd) command); + } else if (command instanceof CreateObjectCommand) { + return execute((CreateObjectCommand) command); + } else if (command instanceof DeleteCommand) { + return execute((DeleteCommand)command); + } else if (command instanceof AttachCommand) { + return execute((AttachCommand)command); + } else if (command instanceof DettachCommand) { + return execute((DettachCommand)command); + } + return new Answer((Command)command, false, "not implemented yet"); + } + + protected Answer execute(CopyCommand cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + + protected Answer execute(AttachPrimaryDataStoreCmd cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + + protected Answer execute(CreatePrimaryDataStoreCmd cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + + protected Answer execute(CreateObjectCommand cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + + protected Answer execute(DeleteCommand cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + + protected Answer execute(AttachCommand cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + + protected Answer execute(DettachCommand cmd) { + return new Answer((Command)cmd, false, "not implemented yet"); + } + +} diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 0f85f4e71ca..f91786fd0af 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -39,6 +39,11 @@ import java.util.UUID; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import org.apache.log4j.NDC; @@ -162,8 +167,11 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.FirewallRuleTO; import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; @@ -177,6 +185,7 @@ import com.cloud.host.Host.Type; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.vmware.manager.VmwareHostService; import com.cloud.hypervisor.vmware.manager.VmwareManager; +import com.cloud.hypervisor.vmware.manager.VmwareStorageMount; import com.cloud.hypervisor.vmware.mo.ClusterMO; import com.cloud.hypervisor.vmware.mo.CustomFieldConstants; import com.cloud.hypervisor.vmware.mo.CustomFieldsManagerMO; @@ -210,8 +219,12 @@ import com.cloud.storage.Storage; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.storage.resource.StoragePoolResource; +import com.cloud.storage.resource.StorageSubsystemCommandHandler; +import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; +import com.cloud.storage.resource.VmwareStorageProcessor; import com.cloud.storage.template.TemplateProp; import com.cloud.utils.DateUtil; +import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.db.DB; @@ -313,6 +326,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa protected Gson _gson; protected volatile long _cmdSequence = 1; + + protected StorageSubsystemCommandHandler storageHandler; protected static HashMap s_statesTable; static { @@ -321,6 +336,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_statesTable.put(VirtualMachinePowerState.POWERED_OFF, State.Stopped); s_statesTable.put(VirtualMachinePowerState.SUSPENDED, State.Stopped); } + + public Gson getGson() { + return this._gson; + } public VmwareResource() { _gson = GsonHelper.getGsonLogger(); @@ -472,6 +491,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((CheckS2SVpnConnectionsCommand) cmd); } else if (clz == ResizeVolumeCommand.class) { return execute((ResizeVolumeCommand) cmd); + } else if (clz == StorageSubSystemCommand.class) { + return this.storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -2026,14 +2047,21 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new CheckSshAnswer(cmd); } - private VolumeTO[] validateDisks(VolumeTO[] disks) { - List validatedDisks = new ArrayList(); + private DiskTO[] validateDisks(DiskTO[] disks) { + List validatedDisks = new ArrayList(); - for (VolumeTO vol : disks) { - if (vol.getPoolUuid() != null && !vol.getPoolUuid().isEmpty()) { - validatedDisks.add(vol); - } else if (vol.getPoolType() == StoragePoolType.ISO && (vol.getPath() != null && !vol.getPath().isEmpty())) { - validatedDisks.add(vol); + for (DiskTO vol : disks) { + if (vol.getType() != Volume.Type.ISO) { + VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); + if (primaryStore.getUuid() != null && !primaryStore.getUuid().isEmpty()) { + validatedDisks.add(vol); + } + } else if (vol.getType() == Volume.Type.ISO) { + TemplateObjectTO templateTO = (TemplateObjectTO)vol.getData(); + if (templateTO.getPath() != null && !templateTO.getPath().isEmpty()) { + validatedDisks.add(vol); + } } else { if (s_logger.isDebugEnabled()) { s_logger.debug("Drop invalid disk option, volumeTO: " + _gson.toJson(vol)); @@ -2041,7 +2069,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - return validatedDisks.toArray(new VolumeTO[0]); + return validatedDisks.toArray(new DiskTO[0]); } protected StartAnswer execute(StartCommand cmd) { @@ -2068,7 +2096,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.debug("VM " + vmName + " will be started with NIC device type: " + nicDeviceType); VmwareHypervisorHost hyperHost = getHyperHost(context); - VolumeTO[] disks = validateDisks(vmSpec.getDisks()); + DiskTO[] disks = validateDisks(vmSpec.getDisks()); assert (disks.length > 0); NicTO[] nics = vmSpec.getNics(); @@ -2105,9 +2133,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else { int ramMb = (int) (vmSpec.getMinRam() / (1024 * 1024)); Pair rootDiskDataStoreDetails = null; - for (VolumeTO vol : disks) { + for (DiskTO vol : disks) { if (vol.getType() == Volume.Type.ROOT) { - rootDiskDataStoreDetails = dataStoresDetails.get(vol.getPoolUuid()); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getData().getDataStore(); + rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid()); } } @@ -2126,12 +2155,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } int totalChangeDevices = disks.length + nics.length; - VolumeTO volIso = null; + DiskTO volIso = null; if (vmSpec.getType() != VirtualMachine.Type.User) { // system VM needs a patch ISO totalChangeDevices++; } else { - for (VolumeTO vol : disks) { + for (DiskTO vol : disks) { if (vol.getType() == Volume.Type.ISO) { volIso = vol; break; @@ -2188,23 +2217,35 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa i++; } else { // we will always plugin a CDROM device - if (volIso != null && volIso.getPath() != null && !volIso.getPath().isEmpty()) { - Pair isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, volIso.getPath()); - assert (isoDatastoreInfo != null); - assert (isoDatastoreInfo.second() != null); + + if (volIso != null) { + TemplateObjectTO iso = (TemplateObjectTO)volIso.getData(); - deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); - Pair isoInfo = VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, i, i + 1); - deviceConfigSpecArray[i].setDevice(isoInfo.first()); - if (isoInfo.second()) { - if(s_logger.isDebugEnabled()) - s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first())); - deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); - } else { - if(s_logger.isDebugEnabled()) - s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first())); - deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT); - } + if (iso.getPath() != null && !iso.getPath().isEmpty()) { + DataStoreTO imageStore = iso.getDataStore(); + if (!(imageStore instanceof NfsTO)) { + s_logger.debug("unsupported protocol"); + throw new Exception("unsupported protocol"); + } + NfsTO nfsImageStore = (NfsTO)imageStore; + String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath(); + Pair isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath); + assert (isoDatastoreInfo != null); + assert (isoDatastoreInfo.second() != null); + + deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); + Pair isoInfo = VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, i, i + 1); + deviceConfigSpecArray[i].setDevice(isoInfo.first()); + if (isoInfo.second()) { + if(s_logger.isDebugEnabled()) + s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first())); + deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); + } else { + if(s_logger.isDebugEnabled()) + s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first())); + deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT); + } + } } else { deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); Pair isoInfo = VmwareHelper.prepareIsoDevice(vmMo, null, null, true, true, i, i + 1); @@ -2224,7 +2265,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa i++; } - for (VolumeTO vol : sortVolumesByDeviceId(disks)) { + for (DiskTO vol : sortVolumesByDeviceId(disks)) { deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); if (vol.getType() == Volume.Type.ISO) { @@ -2247,11 +2288,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } if (vol.getType() != Volume.Type.ISO) { - Pair volumeDsDetails = dataStoresDetails.get(vol.getPoolUuid()); + VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); + Pair volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid()); assert (volumeDsDetails != null); VirtualDevice device; - datastoreDiskPath = String.format("[%s] %s.vmdk", volumeDsDetails.second().getName(), vol.getPath()); - String chainInfo = vol.getChainInfo(); + datastoreDiskPath = String.format("[%s] %s.vmdk", volumeDsDetails.second().getName(), volumeTO.getPath()); + String chainInfo = volumeTO.getChainInfo(); if (chainInfo != null && !chainInfo.isEmpty()) { String[] diskChain = _gson.fromJson(chainInfo, String[].class); @@ -2424,19 +2467,19 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return listForSort.toArray(new NicTO[0]); } - private VolumeTO[] sortVolumesByDeviceId(VolumeTO[] volumes) { + private DiskTO[] sortVolumesByDeviceId(DiskTO[] volumes) { - List listForSort = new ArrayList(); - for (VolumeTO vol : volumes) { + List listForSort = new ArrayList(); + for (DiskTO vol : volumes) { listForSort.add(vol); } - Collections.sort(listForSort, new Comparator() { + Collections.sort(listForSort, new Comparator() { @Override - public int compare(VolumeTO arg0, VolumeTO arg1) { - if (arg0.getDeviceId() < arg1.getDeviceId()) { + public int compare(DiskTO arg0, DiskTO arg1) { + if (arg0.getDiskSeq() < arg1.getDiskSeq()) { return -1; - } else if (arg0.getDeviceId() == arg1.getDeviceId()) { + } else if (arg0.getDiskSeq() == arg1.getDiskSeq()) { return 0; } @@ -2444,16 +2487,18 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } }); - return listForSort.toArray(new VolumeTO[0]); + return listForSort.toArray(new DiskTO[0]); } - private HashMap> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context, VolumeTO[] disks) throws Exception { + private HashMap> inferDatastoreDetailsFromDiskInfo(VmwareHypervisorHost hyperHost, VmwareContext context, DiskTO[] disks) throws Exception { HashMap> poolMors = new HashMap>(); assert (hyperHost != null) && (context != null); - for (VolumeTO vol : disks) { + for (DiskTO vol : disks) { if (vol.getType() != Volume.Type.ISO) { - String poolUuid = vol.getPoolUuid(); + VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); + String poolUuid = primaryStore.getUuid(); if(poolMors.get(poolUuid) == null) { ManagedObjectReference morDataStore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, poolUuid); if (morDataStore == null) { @@ -2461,7 +2506,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.error(msg); throw new Exception(msg); } - poolMors.put(vol.getPoolUuid(), new Pair (morDataStore, new DatastoreMO(context, morDataStore))); + poolMors.put(poolUuid, new Pair (morDataStore, new DatastoreMO(context, morDataStore))); } } } @@ -3306,7 +3351,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - private synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception { + public synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception { String storeName = getSecondaryDatastoreUUID(storeUrl); URI uri = new URI(storeUrl); @@ -3670,8 +3715,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - @Override - public Answer execute(DestroyCommand cmd) { + + public Answer execute(DeleteCommand cmd) { if (s_logger.isInfoEnabled()) { s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd)); } @@ -3691,11 +3736,12 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa try { VmwareContext context = getServiceContext(); VmwareHypervisorHost hyperHost = getHyperHost(context); - VolumeTO vol = cmd.getVolume(); + VolumeObjectTO vol = (VolumeObjectTO)cmd.getData(); + PrimaryDataStoreTO store = (PrimaryDataStoreTO)vol.getDataStore(); - ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, vol.getPoolUuid()); + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, store.getUuid()); if (morDs == null) { - String msg = "Unable to find datastore based on volume mount point " + cmd.getVolume().getMountPoint(); + String msg = "Unable to find datastore based on volume mount point " + store.getPath(); s_logger.error(msg); throw new Exception(msg); } @@ -3706,8 +3752,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa ManagedObjectReference morCluster = hyperHost.getHyperHostCluster(); ClusterMO clusterMo = new ClusterMO(context, morCluster); - if (cmd.getVolume().getType() == Volume.Type.ROOT) { - String vmName = cmd.getVmName(); + if (vol.getVolumeType() == Volume.Type.ROOT) { + String vmName = vol.getVmName(); if (vmName != null) { VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName); if (vmMo != null) { @@ -3734,20 +3780,20 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } if (s_logger.isInfoEnabled()) - s_logger.info("Destroy volume by original name: " + cmd.getVolume().getPath() + ".vmdk"); - dsMo.deleteFile(cmd.getVolume().getPath() + ".vmdk", morDc, true); + s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk"); + dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); // root volume may be created via linked-clone, delete the delta disk as well if (_fullCloneFlag) { if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy volume by derived name: " + cmd.getVolume().getPath() + "-flat.vmdk"); + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-flat.vmdk"); } - dsMo.deleteFile(cmd.getVolume().getPath() + "-flat.vmdk", morDc, true); + dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true); } else { if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy volume by derived name: " + cmd.getVolume().getPath() + "-delta.vmdk"); + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-delta.vmdk"); } - dsMo.deleteFile(cmd.getVolume().getPath() + "-delta.vmdk", morDc, true); + dsMo.deleteFile(vol.getPath() + "-delta.vmdk", morDc, true); } return new Answer(cmd, true, "Success"); } @@ -3757,17 +3803,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } else { // evitTemplate will be converted into DestroyCommand, test if we are running in this case - VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(cmd.getVolume().getPath()); + VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vol.getPath()); if (vmMo != null) { if (s_logger.isInfoEnabled()) - s_logger.info("Destroy template volume " + cmd.getVolume().getPath()); + s_logger.info("Destroy template volume " + vol.getPath()); vmMo.destroy(); return new Answer(cmd, true, "Success"); } } - String chainInfo = cmd.getVolume().getChainInfo(); + String chainInfo = vol.getChainInfo(); if (chainInfo != null && !chainInfo.isEmpty()) { s_logger.info("Destroy volume by chain info: " + chainInfo); String[] diskChain = _gson.fromJson(chainInfo, String[].class); @@ -3783,23 +3829,23 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (s_logger.isInfoEnabled()) { s_logger.info("Empty disk chain info, fall back to try to delete by original backing file name"); } - dsMo.deleteFile(cmd.getVolume().getPath() + ".vmdk", morDc, true); + dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy volume by derived name: " + cmd.getVolume().getPath() + "-flat.vmdk"); + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-flat.vmdk"); } - dsMo.deleteFile(cmd.getVolume().getPath() + "-flat.vmdk", morDc, true); + dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true); } } else { if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy volume by original name: " + cmd.getVolume().getPath() + ".vmdk"); + s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk"); } - dsMo.deleteFile(cmd.getVolume().getPath() + ".vmdk", morDc, true); + dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); if (s_logger.isInfoEnabled()) { - s_logger.info("Destroy volume by derived name: " + cmd.getVolume().getPath() + "-flat.vmdk"); + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-flat.vmdk"); } - dsMo.deleteFile(cmd.getVolume().getPath() + "-flat.vmdk", morDc, true); + dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true); } return new Answer(cmd, true, "Success"); @@ -3815,7 +3861,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - private void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { + public void cleanupNetwork(HostMO hostMo, NetworkDetails netDetails) { // we will no longer cleanup VLAN networks in order to support native VMware HA /* * assert(netDetails.getName() != null); try { synchronized(this) { NetworkMO networkMo = new @@ -4857,7 +4903,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return s_statesTable.get(powerState); } - private static State getVmState(VirtualMachineMO vmMo) throws Exception { + public static State getVmState(VirtualMachineMO vmMo) throws Exception { VirtualMachineRuntimeInfo runtimeInfo = vmMo.getRuntimeInfo(); return convertState(runtimeInfo.getPowerState()); } @@ -4991,6 +5037,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } else { _fullCloneFlag = false; } + value = (String)params.get("scripts.timeout"); + int timeout = NumbersUtil.parseInt(value, 1440) * 1000; + VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME); + VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, this._fullCloneFlag, (VmwareStorageMount)mgr, + timeout, this, this._shutdown_waitMs + ); + storageHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); return true; } @@ -5010,15 +5063,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return true; } - private VmwareContext getServiceContext() { + public VmwareContext getServiceContext() { return getServiceContext(null); } - private void invalidateServiceContext() { + public void invalidateServiceContext() { invalidateServiceContext(null); } - private VmwareHypervisorHost getHyperHost(VmwareContext context) { + public VmwareHypervisorHost getHyperHost(VmwareContext context) { return getHyperHost(context, null); } @@ -5115,4 +5168,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // TODO Auto-generated method stub } + + @Override + public Answer execute(DestroyCommand cmd) { + // TODO Auto-generated method stub + return null; + } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java index 566e750c3fe..645b6d30380 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java @@ -18,6 +18,7 @@ package com.cloud.storage.resource; import java.util.List; +import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; @@ -29,6 +30,7 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.hypervisor.vmware.manager.VmwareHostService; +import com.cloud.hypervisor.vmware.manager.VmwareManager; import com.cloud.hypervisor.vmware.manager.VmwareStorageManager; import com.cloud.hypervisor.vmware.manager.VmwareStorageManagerImpl; import com.cloud.hypervisor.vmware.manager.VmwareStorageMount; @@ -51,6 +53,7 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe private final VmwareStorageManager _storageMgr; private final Gson _gson; + private StorageSubsystemCommandHandler storageSubsystemHandler; /* private Map _activeHosts = new HashMap(); @@ -60,6 +63,11 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe _resource = resource; _storageMgr = new VmwareStorageManagerImpl(this); _gson = GsonHelper.getGsonLogger(); + + VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor((VmwareHostService)this, true, (VmwareStorageMount)this, + null, null, null + ); + storageSubsystemHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); } @Override @@ -77,6 +85,8 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe answer = execute((CopyVolumeCommand)cmd); } else if(cmd instanceof CreateVolumeFromSnapshotCommand) { answer = execute((CreateVolumeFromSnapshotCommand)cmd); + } else if (cmd instanceof StorageSubSystemCommand) { + answer = storageSubsystemHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else { answer = _resource.defaultAction(cmd); } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java new file mode 100644 index 00000000000..988658dbc7c --- /dev/null +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -0,0 +1,1144 @@ +package com.cloud.storage.resource; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStreamWriter; +import java.net.URI; +import java.rmi.RemoteException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.cloudstack.storage.command.AttachAnswer; +import org.apache.cloudstack.storage.command.AttachCommand; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.CreateObjectAnswer; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.command.DettachCommand; +import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; +import org.apache.cloudstack.storage.to.SnapshotObjectTO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.BackupSnapshotAnswer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.ManageSnapshotAnswer; +import com.cloud.agent.api.ManageSnapshotCommand; +import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; +import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NfsTO; +import com.cloud.agent.api.to.VolumeTO; +import com.cloud.hypervisor.vmware.manager.VmwareHostService; +import com.cloud.hypervisor.vmware.manager.VmwareStorageMount; +import com.cloud.hypervisor.vmware.mo.ClusterMO; +import com.cloud.hypervisor.vmware.mo.CustomFieldConstants; +import com.cloud.hypervisor.vmware.mo.DatacenterMO; +import com.cloud.hypervisor.vmware.mo.DatastoreMO; +import com.cloud.hypervisor.vmware.mo.HostMO; +import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; +import com.cloud.hypervisor.vmware.mo.NetworkDetails; +import com.cloud.hypervisor.vmware.mo.VirtualMachineMO; +import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; +import com.cloud.hypervisor.vmware.resource.VmwareResource; +import com.cloud.hypervisor.vmware.util.VmwareContext; +import com.cloud.hypervisor.vmware.util.VmwareHelper; +import com.cloud.serializer.GsonHelper; +import com.cloud.storage.JavaStorageLayer; +import com.cloud.storage.StorageLayer; +import com.cloud.storage.Volume; +import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.template.VmdkProcessor; +import com.cloud.utils.Pair; +import com.cloud.utils.StringUtils; +import com.cloud.utils.Ternary; +import com.cloud.utils.script.Script; +import com.cloud.vm.VirtualMachine.State; +import com.google.gson.Gson; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.VirtualDeviceConfigSpec; +import com.vmware.vim25.VirtualDeviceConfigSpecOperation; +import com.vmware.vim25.VirtualDisk; +import com.vmware.vim25.VirtualEthernetCard; +import com.vmware.vim25.VirtualLsiLogicController; +import com.vmware.vim25.VirtualMachineConfigSpec; +import com.vmware.vim25.VirtualMachineFileInfo; +import com.vmware.vim25.VirtualMachineGuestOsIdentifier; +import com.vmware.vim25.VirtualSCSISharing; + +public class VmwareStorageProcessor implements StorageProcessor { + private static final Logger s_logger = Logger.getLogger(VmwareStorageProcessor.class); + private VmwareHostService hostService; + private boolean _fullCloneFlag; + private VmwareStorageMount mountService; + private VmwareResource resource; + private Integer _timeout; + protected Integer _shutdown_waitMs; + private final Gson _gson; + private final StorageLayer _storage = new JavaStorageLayer(); + public VmwareStorageProcessor(VmwareHostService hostService, boolean fullCloneFlag, VmwareStorageMount mountService, + Integer timeout, + VmwareResource resource, + Integer shutdownWaitMs) { + this.hostService = hostService; + this._fullCloneFlag = fullCloneFlag; + this.mountService = mountService; + this._timeout = timeout; + this.resource = resource; + this._shutdown_waitMs = shutdownWaitMs; + _gson = GsonHelper.getGsonLogger(); + } + + private String getOVFFilePath(String srcOVAFileName) { + File file = new File(srcOVAFileName); + assert(_storage != null); + String[] files = _storage.listFiles(file.getParent()); + if(files != null) { + for(String fileName : files) { + if(fileName.toLowerCase().endsWith(".ovf")) { + File ovfFile = new File(fileName); + return file.getParent() + File.separator + ovfFile.getName(); + } + } + } + return null; + } + private void copyTemplateFromSecondaryToPrimary(VmwareHypervisorHost hyperHost, DatastoreMO datastoreMo, String secondaryStorageUrl, + String templatePathAtSecondaryStorage, String templateName, String templateUuid) throws Exception { + + s_logger.info("Executing copyTemplateFromSecondaryToPrimary. secondaryStorage: " + + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + + ", templateName: " + templateName); + + String secondaryMountPoint = mountService.getMountPoint(secondaryStorageUrl); + s_logger.info("Secondary storage mount point: " + secondaryMountPoint); + + String srcOVAFileName = secondaryMountPoint + "/" + templatePathAtSecondaryStorage + + templateName + "." + ImageFormat.OVA.getFileExtension(); + + String srcFileName = getOVFFilePath(srcOVAFileName); + if(srcFileName == null) { + Script command = new Script("tar", 0, s_logger); + command.add("--no-same-owner"); + command.add("-xf", srcOVAFileName); + command.setWorkDir(secondaryMountPoint + "/" + templatePathAtSecondaryStorage); + s_logger.info("Executing command: " + command.toString()); + String result = command.execute(); + if(result != null) { + String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); + } + } + + srcFileName = getOVFFilePath(srcOVAFileName); + if(srcFileName == null) { + String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); + } + + String vmName = templateUuid; + hyperHost.importVmFromOVF(srcFileName, vmName, datastoreMo, "thin"); + + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + if(vmMo == null) { + String msg = "Failed to import OVA template. secondaryStorage: " + + secondaryStorageUrl + ", templatePathAtSecondaryStorage: " + templatePathAtSecondaryStorage + + ", templateName: " + templateName + ", templateUuid: " + templateUuid; + s_logger.error(msg); + throw new Exception(msg); + } + + if(vmMo.createSnapshot("cloud.template.base", "Base snapshot", false, false)) { + vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_UUID, templateUuid); + vmMo.markAsTemplate(); + } else { + vmMo.destroy(); + String msg = "Unable to create base snapshot for template, templateName: " + templateName + ", templateUuid: " + templateUuid; + s_logger.error(msg); + throw new Exception(msg); + } + } + + @Override + public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + TemplateObjectTO template = (TemplateObjectTO)srcData; + DataStoreTO srcStore = srcData.getDataStore(); + if (!(srcStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + NfsTO nfsImageStore = (NfsTO)srcStore; + DataTO destData = cmd.getDestTO(); + DataStoreTO destStore = destData.getDataStore(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destStore; + String secondaryStorageUrl = nfsImageStore.getUrl(); + assert (secondaryStorageUrl != null); + + String templateUrl = secondaryStorageUrl + File.separator + srcData.getPath(); + + String templateName = null; + String mountPoint = null; + if (templateUrl.endsWith(".ova")) { + int index = templateUrl.lastIndexOf("/"); + mountPoint = templateUrl.substring(0, index); + mountPoint = mountPoint.substring(secondaryStorageUrl.length() + 1); + if (!mountPoint.endsWith("/")) { + mountPoint = mountPoint + "/"; + } + + templateName = templateUrl.substring(index + 1).replace("." + ImageFormat.OVA.getFileExtension(), ""); + + if (templateName == null || templateName.isEmpty()) { + templateName = template.getName(); + } + } else { + mountPoint = templateUrl.substring(secondaryStorageUrl.length() + 1); + if (!mountPoint.endsWith("/")) { + mountPoint = mountPoint + "/"; + } + templateName = template.getName(); + } + + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + + String templateUuidName = UUID.nameUUIDFromBytes((templateName + "@" + primaryStore.getUuid() + "-" + hyperHost.getMor().getValue()).getBytes()).toString(); + // truncate template name to 32 chars to ensure they work well with vSphere API's. + templateUuidName = templateUuidName.replace("-", ""); + + DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); + VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true); + + if (templateMo == null) { + if(s_logger.isInfoEnabled()) + s_logger.info("Template " + templateName + " is not setup yet, setup template from secondary storage with uuid name: " + templateUuidName); + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); + assert (morDs != null); + DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs); + + copyTemplateFromSecondaryToPrimary(hyperHost, + primaryStorageDatastoreMo, secondaryStorageUrl, + mountPoint, templateName, templateUuidName); + } else { + s_logger.info("Template " + templateName + " has already been setup, skip the template setup process in primary storage"); + } + + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(templateUuidName); + return new CopyCmdAnswer(newTemplate); + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } + + String msg = "Unable to execute PrimaryStorageDownloadCommand due to exception"; + s_logger.error(msg, e); + return new CopyCmdAnswer(msg); + } + } + private boolean createVMLinkedClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, + String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception { + + ManagedObjectReference morBaseSnapshot = vmTemplate.getSnapshotMor("cloud.template.base"); + if (morBaseSnapshot == null) { + String msg = "Unable to find template base snapshot, invalid template"; + s_logger.error(msg); + throw new Exception(msg); + } + + if(dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) + dsMo.deleteFile(String.format("[%s] %s/", dsMo.getName(), vmdkName), dcMo.getMor(), false); + + s_logger.info("creating linked clone from template"); + if (!vmTemplate.createLinkedClone(vmdkName, morBaseSnapshot, dcMo.getVmFolder(), morPool, morDatastore)) { + String msg = "Unable to clone from the template"; + s_logger.error(msg); + throw new Exception(msg); + } + + // we can't rely on un-offical API (VirtualMachineMO.moveAllVmDiskFiles() any more, use hard-coded disk names that we know + // to move files + s_logger.info("Move volume out of volume-wrapper VM "); + dsMo.moveDatastoreFile(String.format("[%s] %s/%s.vmdk", dsMo.getName(), vmdkName, vmdkName), + dcMo.getMor(), dsMo.getMor(), + String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + + dsMo.moveDatastoreFile(String.format("[%s] %s/%s-delta.vmdk", dsMo.getName(), vmdkName, vmdkName), + dcMo.getMor(), dsMo.getMor(), + String.format("[%s] %s-delta.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + + return true; + } + + private boolean createVMFullClone(VirtualMachineMO vmTemplate, DatacenterMO dcMo, DatastoreMO dsMo, + String vmdkName, ManagedObjectReference morDatastore, ManagedObjectReference morPool) throws Exception { + + if(dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmdkName)) + dsMo.deleteFile(String.format("[%s] %s/", dsMo.getName(), vmdkName), dcMo.getMor(), false); + + s_logger.info("creating full clone from template"); + if (!vmTemplate.createFullClone(vmdkName, dcMo.getVmFolder(), morPool, morDatastore)) { + String msg = "Unable to create full clone from the template"; + s_logger.error(msg); + throw new Exception(msg); + } + + // we can't rely on un-offical API (VirtualMachineMO.moveAllVmDiskFiles() any more, use hard-coded disk names that we know + // to move files + s_logger.info("Move volume out of volume-wrapper VM "); + dsMo.moveDatastoreFile(String.format("[%s] %s/%s.vmdk", dsMo.getName(), vmdkName, vmdkName), + dcMo.getMor(), dsMo.getMor(), + String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + + dsMo.moveDatastoreFile(String.format("[%s] %s/%s-flat.vmdk", dsMo.getName(), vmdkName, vmdkName), + dcMo.getMor(), dsMo.getMor(), + String.format("[%s] %s-flat.vmdk", dsMo.getName(), vmdkName), dcMo.getMor(), true); + + return true; + } + + @Override + public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + TemplateObjectTO template = (TemplateObjectTO)srcData; + DataStoreTO imageStore = template.getDataStore(); + DataTO destData = cmd.getDestTO(); + VolumeObjectTO volume = (VolumeObjectTO)destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + if (imageStore != null && !(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + NfsTO nfsImageStore = (NfsTO)imageStore; + + try { + VmwareContext context = this.hostService.getServiceContext(null); + VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(context, null); + DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); + VirtualMachineMO vmMo = null; + ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); + if (morDatastore == null) + throw new Exception("Unable to find datastore in vSphere"); + + DatastoreMO dsMo = new DatastoreMO(context, morDatastore); + + + // attach volume id to make the name unique + String vmdkName = volume.getName() + "-" + volume.getId(); + if (nfsImageStore == null) { + // create a root volume for blank VM + String dummyVmName = this.hostService.getWorkerName(context, cmd, 0); + + try { + vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName); + if (vmMo == null) { + throw new Exception("Unable to create a dummy VM for volume creation"); + } + + String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), vmdkName); + synchronized (this) { + s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath); + VmwareHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo); + vmMo.createDisk(volumeDatastorePath, (int) (volume.getSize() / (1024L * 1024L)), morDatastore, -1); + vmMo.detachDisk(volumeDatastorePath, false); + } + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(vmdkName); + return new CopyCmdAnswer(newVol); + } finally { + vmMo.detachAllDisks(); + + s_logger.info("Destroy dummy VM after volume creation"); + vmMo.destroy(); + } + } else { + String templateUrl = nfsImageStore.getUrl() + File.separator + template.getPath(); + VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUrl), true); + if (vmTemplate == null) { + s_logger.warn("Template host in vSphere is not in connected state, request template reload"); + return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload"); + } + + ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool(); + ManagedObjectReference morCluster = hyperHost.getHyperHostCluster(); + //createVMLinkedClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool); + if (!_fullCloneFlag) { + createVMLinkedClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool); + } else { + createVMFullClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool); + } + + vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName); + assert (vmMo != null); + + s_logger.info("detach disks from volume-wrapper VM " + vmdkName); + vmMo.detachAllDisks(); + + s_logger.info("destroy volume-wrapper VM " + vmdkName); + vmMo.destroy(); + + String srcFile = String.format("[%s] %s/", dsMo.getName(), vmdkName); + dsMo.deleteFile(srcFile, dcMo.getMor(), true); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(vmdkName); + return new CopyCmdAnswer(newVol); + } + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + this.hostService.invalidateServiceContext(null); + } + + String msg = "CreateCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new CopyCmdAnswer(e.toString()); + } + } + + + @Override + public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { + // TODO Auto-generated method stub + return null; + } + + @Override + public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { + // TODO Auto-generated method stub + return null; + } + + private void postCreatePrivateTemplate(String installFullPath, long templateId, + String templateName, long size, long virtualSize) throws Exception { + + // TODO a bit ugly here + BufferedWriter out = null; + try { + out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(installFullPath + "/template.properties"))); + out.write("filename=" + templateName + ".ova"); + out.newLine(); + out.write("description="); + out.newLine(); + out.write("checksum="); + out.newLine(); + out.write("hvm=false"); + out.newLine(); + out.write("size=" + size); + out.newLine(); + out.write("ova=true"); + out.newLine(); + out.write("id=" + templateId); + out.newLine(); + out.write("public=false"); + out.newLine(); + out.write("ova.filename=" + templateName + ".ova"); + out.newLine(); + out.write("uniquename=" + templateName); + out.newLine(); + out.write("ova.virtualsize=" + virtualSize); + out.newLine(); + out.write("virtualsize=" + virtualSize); + out.newLine(); + out.write("ova.size=" + size); + out.newLine(); + } finally { + if(out != null) + out.close(); + } + } + + private Ternary createTemplateFromVolume(VirtualMachineMO vmMo, String installPath, long templateId, String templateUniqueName, + String secStorageUrl, String volumePath, String workerVmName) throws Exception { + + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String installFullPath = secondaryMountPoint + "/" + installPath; + synchronized(installPath.intern()) { + Script command = new Script(false, "mkdir", _timeout, s_logger); + command.add("-p"); + command.add(installFullPath); + + String result = command.execute(); + if(result != null) { + String msg = "unable to prepare template directory: " + + installPath + ", storage: " + secStorageUrl + ", error msg: " + result; + s_logger.error(msg); + throw new Exception(msg); + } + } + + VirtualMachineMO clonedVm = null; + try { + Pair volumeDeviceInfo = vmMo.getDiskDevice(volumePath, false); + if(volumeDeviceInfo == null) { + String msg = "Unable to find related disk device for volume. volume path: " + volumePath; + s_logger.error(msg); + throw new Exception(msg); + } + + if(!vmMo.createSnapshot(templateUniqueName, "Temporary snapshot for template creation", false, false)) { + String msg = "Unable to take snapshot for creating template from volume. volume path: " + volumePath; + s_logger.error(msg); + throw new Exception(msg); + } + + // 4 MB is the minimum requirement for VM memory in VMware + vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), + VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName); + if(clonedVm == null) { + String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath; + s_logger.error(msg); + throw new Exception(msg); + } + + clonedVm.exportVm(secondaryMountPoint + "/" + installPath, templateUniqueName, true, false); + + long physicalSize = new File(installFullPath + "/" + templateUniqueName + ".ova").length(); + VmdkProcessor processor = new VmdkProcessor(); + Map params = new HashMap(); + params.put(StorageLayer.InstanceConfigKey, _storage); + processor.configure("VMDK Processor", params); + long virtualSize = processor.getTemplateVirtualSize(installFullPath, templateUniqueName); + + postCreatePrivateTemplate(installFullPath, templateId, templateUniqueName, physicalSize, virtualSize); + return new Ternary(installPath + "/" + templateUniqueName + ".ova", physicalSize, virtualSize); + + } finally { + if(clonedVm != null) { + clonedVm.detachAllDisks(); + clonedVm.destroy(); + } + + vmMo.removeSnapshot(templateUniqueName, false); + } + } + + @Override + public Answer createTemplateFromVolume(CopyCommand cmd) { + VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO(); + DataStoreTO imageStore = template.getDataStore(); + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + NfsTO nfsImageStore = (NfsTO)imageStore; + String secondaryStoragePoolURL = nfsImageStore.getUrl(); + String volumePath = volume.getPath(); + + String details = null; + + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(volume.getVmName()); + if (vmMo == null) { + if(s_logger.isDebugEnabled()) + s_logger.debug("Unable to find the owner VM for CreatePrivateTemplateFromVolumeCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter"); + vmMo = hyperHost.findVmOnPeerHyperHost(volume.getVmName()); + + if(vmMo == null) { + String msg = "Unable to find the owner VM for volume operation. vm: " + volume.getVmName(); + s_logger.error(msg); + throw new Exception(msg); + } + } + + Ternary result = createTemplateFromVolume(vmMo, + template.getPath(), template.getId(), template.getName(), + secondaryStoragePoolURL, volumePath, + hostService.getWorkerName(context, cmd, 0)); + + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(template.getName()); + newTemplate.setFormat(ImageFormat.OVA); + return new CopyCmdAnswer(newTemplate); + + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } + + s_logger.error("Unexpecpted exception ", e); + + details = "CreatePrivateTemplateFromVolumeCommand exception: " + StringUtils.getExceptionStackInfo(e); + return new CopyCmdAnswer(details); + } + } + + private void exportVolumeToSecondaryStroage(VirtualMachineMO vmMo, String volumePath, + String secStorageUrl, String secStorageDir, String exportName, + String workerVmName) throws Exception { + + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String exportPath = secondaryMountPoint + "/" + secStorageDir + "/" + exportName; + + synchronized(exportPath.intern()) { + if(!new File(exportPath).exists()) { + Script command = new Script(false, "mkdir", _timeout, s_logger); + command.add("-p"); + command.add(exportPath); + if(command.execute() != null) + throw new Exception("unable to prepare snapshot backup directory"); + } + } + + VirtualMachineMO clonedVm = null; + try { + + Pair volumeDeviceInfo = vmMo.getDiskDevice(volumePath, false); + if(volumeDeviceInfo == null) { + String msg = "Unable to find related disk device for volume. volume path: " + volumePath; + s_logger.error(msg); + throw new Exception(msg); + } + + // 4 MB is the minimum requirement for VM memory in VMware + vmMo.cloneFromCurrentSnapshot(workerVmName, 0, 4, volumeDeviceInfo.second(), + VmwareHelper.getDiskDeviceDatastore(volumeDeviceInfo.first())); + clonedVm = vmMo.getRunningHost().findVmOnHyperHost(workerVmName); + if(clonedVm == null) { + String msg = "Unable to create dummy VM to export volume. volume path: " + volumePath; + s_logger.error(msg); + throw new Exception(msg); + } + + clonedVm.exportVm(exportPath, exportName, true, true); + } finally { + if(clonedVm != null) { + clonedVm.detachAllDisks(); + clonedVm.destroy(); + } + } + } + + + private String backupSnapshotToSecondaryStorage(VirtualMachineMO vmMo, String installPath, + String volumePath, String snapshotUuid, String secStorageUrl, + String prevSnapshotUuid, String prevBackupUuid, String workerVmName) throws Exception { + + String backupUuid = UUID.randomUUID().toString(); + exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, + installPath, backupUuid, workerVmName); + return backupUuid + "/" + backupUuid; + } + @Override + public Answer backupSnasphot(CopyCommand cmd) { + SnapshotObjectTO srcSnapshot = (SnapshotObjectTO)cmd.getSrcTO(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcSnapshot.getDataStore(); + SnapshotObjectTO destSnapshot = (SnapshotObjectTO)cmd.getDestTO(); + DataStoreTO destStore = destSnapshot.getDataStore(); + if (!(destStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + + NfsTO destNfsStore = (NfsTO)destStore; + + + String secondaryStorageUrl = destNfsStore.getUrl(); + String snapshotUuid = srcSnapshot.getPath(); + String prevSnapshotUuid = srcSnapshot.getParentSnapshotPath(); + String prevBackupUuid = destSnapshot.getParentSnapshotPath(); + VirtualMachineMO workerVm=null; + String workerVMName = null; + String volumePath = srcSnapshot.getVolume().getPath(); + ManagedObjectReference morDs = null; + DatastoreMO dsMo=null; + + // By default assume failure + String details = null; + boolean success = false; + String snapshotBackupUuid = null; + + VmwareContext context = hostService.getServiceContext(cmd); + VirtualMachineMO vmMo = null; + String vmName = srcSnapshot.getVmName(); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); + + try { + vmMo = hyperHost.findVmOnHyperHost(vmName); + if (vmMo == null) { + if(s_logger.isDebugEnabled()) + s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter"); + + vmMo = hyperHost.findVmOnPeerHyperHost(vmName); + if(vmMo == null) { + dsMo = new DatastoreMO(hyperHost.getContext(), morDs); + + workerVMName = hostService.getWorkerName(context, cmd, 0); + + // attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup + if (!hyperHost.createBlankVm(workerVMName, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier.OTHER_GUEST.value(), morDs, false)) { + String msg = "Unable to create worker VM to execute BackupSnapshotCommand"; + s_logger.error(msg); + throw new Exception(msg); + } + vmMo = hyperHost.findVmOnHyperHost(workerVMName); + if (vmMo == null) { + throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); + } + workerVm = vmMo; + + // attach volume to worker VM + String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumePath); + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); + } + } + + if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + srcSnapshot.getName(), false, false)) { + throw new Exception("Failed to take snapshot " + srcSnapshot.getName() + " on vm: " + vmName); + } + + snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, destSnapshot.getPath(), srcSnapshot.getVolume().getPath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid, + hostService.getWorkerName(context, cmd, 1)); + + success = (snapshotBackupUuid != null); + if (success) { + details = "Successfully backedUp the snapshotUuid: " + snapshotUuid + " to secondary storage."; + return new CopyCmdAnswer(details); + } else { + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + newSnapshot.setPath(snapshotBackupUuid); + return new CopyCmdAnswer(newSnapshot); + } + } finally { + if(vmMo != null){ + ManagedObjectReference snapshotMor = vmMo.getSnapshotMor(snapshotUuid); + if (snapshotMor != null){ + vmMo.removeSnapshot(snapshotUuid, false); + } + } + + try { + if (workerVm != null) { + // detach volume and destroy worker vm + workerVm.detachAllDisks(); + workerVm.destroy(); + } + } catch (Throwable e) { + s_logger.warn("Failed to destroy worker VM: " + workerVMName); + } + } + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } + + s_logger.error("Unexpecpted exception ", e); + + details = "BackupSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); + return new CopyCmdAnswer(details); + } + } + + @Override + public Answer attachIso(AttachCommand cmd) { + return this.attachIso(cmd.getDisk(), true, cmd.getVmName()); + } + + @Override + public Answer attachVolume(AttachCommand cmd) { + return this.attachVolume(cmd, cmd.getDisk(), true, cmd.getVmName()); + } + + private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, String vmName) { + + VolumeObjectTO volumeTO = (VolumeObjectTO)disk.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); + try { + VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(this.hostService.getServiceContext(null), null); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + if (vmMo == null) { + String msg = "Unable to find the VM to execute AttachVolumeCommand, vmName: " + vmName; + s_logger.error(msg); + throw new Exception(msg); + } + + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); + if (morDs == null) { + String msg = "Unable to find the mounted datastore to execute AttachVolumeCommand, vmName: " + vmName; + s_logger.error(msg); + throw new Exception(msg); + } + + DatastoreMO dsMo = new DatastoreMO(this.hostService.getServiceContext(null), morDs); + String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeTO.getPath()); + + AttachAnswer answer = new AttachAnswer(disk); + if (isAttach) { + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); + } else { + vmMo.removeAllSnapshots(); + vmMo.detachDisk(datastoreVolumePath, false); + } + + return answer; + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + this.hostService.invalidateServiceContext(null); + } + + String msg = "AttachVolumeCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new AttachAnswer(msg); + } + } + + private static String getSecondaryDatastoreUUID(String storeUrl) { + return UUID.nameUUIDFromBytes(storeUrl.getBytes()).toString(); + } + + public synchronized ManagedObjectReference prepareSecondaryDatastoreOnHost(String storeUrl) throws Exception { + String storeName = getSecondaryDatastoreUUID(storeUrl); + URI uri = new URI(storeUrl); + + VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(this.hostService.getServiceContext(null), null); + ManagedObjectReference morDatastore = hyperHost.mountDatastore(false, uri.getHost(), 0, uri.getPath(), storeName.replace("-", "")); + + if (morDatastore == null) + throw new Exception("Unable to mount secondary storage on host. storeUrl: " + storeUrl); + + return morDatastore; + } + private Answer attachIso(DiskTO disk, boolean isAttach, String vmName) { + + + try { + VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(this.hostService.getServiceContext(null), null); + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName); + if (vmMo == null) { + String msg = "Unable to find VM in vSphere to execute AttachIsoCommand, vmName: " + vmName; + s_logger.error(msg); + throw new Exception(msg); + } + TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); + NfsTO nfsImageStore = (NfsTO)iso.getDataStore(); + String storeUrl = nfsImageStore.getUrl(); + if (storeUrl == null) { + if (!iso.getName().equalsIgnoreCase("vmware-tools.iso")) { + String msg = "ISO store root url is not found in AttachIsoCommand"; + s_logger.error(msg); + throw new Exception(msg); + } else { + if (isAttach) { + vmMo.mountToolsInstaller(); + } else { + try{ + vmMo.unmountToolsInstaller(); + }catch(Throwable e){ + vmMo.detachIso(null); + } + } + + return new AttachAnswer(disk); + } + } + + ManagedObjectReference morSecondaryDs = prepareSecondaryDatastoreOnHost(storeUrl); + String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath(); + if (!isoPath.startsWith(storeUrl)) { + assert (false); + String msg = "ISO path does not start with the secondary storage root"; + s_logger.error(msg); + throw new Exception(msg); + } + + int isoNameStartPos = isoPath.lastIndexOf('/'); + String isoFileName = isoPath.substring(isoNameStartPos + 1); + String isoStorePathFromRoot = isoPath.substring(storeUrl.length(), isoNameStartPos); + + // TODO, check if iso is already attached, or if there is a previous + // attachment + DatastoreMO secondaryDsMo = new DatastoreMO(this.hostService.getServiceContext(null), morSecondaryDs); + String storeName = secondaryDsMo.getName(); + String isoDatastorePath = String.format("[%s] %s%s", storeName, isoStorePathFromRoot, isoFileName); + + if (isAttach) { + vmMo.attachIso(isoDatastorePath, morSecondaryDs, true, false); + } else { + vmMo.detachIso(isoDatastorePath); + } + + return new AttachAnswer(disk); + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + this.hostService.invalidateServiceContext(null); + } + + if(isAttach) { + String msg = "AttachIsoCommand(attach) failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new AttachAnswer(msg); + } else { + String msg = "AttachIsoCommand(detach) failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.warn(msg, e); + return new AttachAnswer(msg); + } + } + } + @Override + public Answer dettachIso(DettachCommand cmd) { + return this.attachIso(cmd.getDisk(), false, cmd.getVmName()); + } + + @Override + public Answer dettachVolume(DettachCommand cmd) { + return this.attachVolume(cmd, cmd.getDisk(), false, cmd.getVmName()); + } + + protected VirtualMachineMO prepareVolumeHostDummyVm(VmwareHypervisorHost hyperHost, DatastoreMO dsMo, String vmName) throws Exception { + assert (hyperHost != null); + + VirtualMachineMO vmMo = null; + VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec(); + vmConfig.setName(vmName); + vmConfig.setMemoryMB((long) 4); // vmware request minimum of 4 MB + vmConfig.setNumCPUs(1); + vmConfig.setGuestId(VirtualMachineGuestOsIdentifier.OTHER_GUEST.value()); + VirtualMachineFileInfo fileInfo = new VirtualMachineFileInfo(); + fileInfo.setVmPathName(String.format("[%s]", dsMo.getName())); + vmConfig.setFiles(fileInfo); + + // Scsi controller + VirtualLsiLogicController scsiController = new VirtualLsiLogicController(); + scsiController.setSharedBus(VirtualSCSISharing.NO_SHARING); + scsiController.setBusNumber(0); + scsiController.setKey(1); + VirtualDeviceConfigSpec scsiControllerSpec = new VirtualDeviceConfigSpec(); + scsiControllerSpec.setDevice(scsiController); + scsiControllerSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); + + vmConfig.getDeviceChange().add(scsiControllerSpec ); + hyperHost.createVm(vmConfig); + vmMo = hyperHost.findVmOnHyperHost(vmName); + return vmMo; + } + @Override + public Answer createVolume(CreateObjectCommand cmd) { + + VolumeObjectTO volume = (VolumeObjectTO)cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + + try { + VmwareContext context = this.hostService.getServiceContext(null); + VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(context, null); + DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter()); + + ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid()); + if (morDatastore == null) + throw new Exception("Unable to find datastore in vSphere"); + + DatastoreMO dsMo = new DatastoreMO(context, morDatastore); + // create data volume + VirtualMachineMO vmMo = null; + String volumeUuid = UUID.randomUUID().toString().replace("-", ""); + String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeUuid); + String dummyVmName = this.hostService.getWorkerName(context, cmd, 0); + try { + vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName); + if (vmMo == null) { + throw new Exception("Unable to create a dummy VM for volume creation"); + } + + synchronized (this) { + // s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath); + VmwareHelper.deleteVolumeVmdkFiles(dsMo, volumeUuid.toString(), dcMo); + + vmMo.createDisk(volumeDatastorePath, (int) (volume.getSize() / (1024L * 1024L)), morDatastore, vmMo.getScsiDeviceControllerKey()); + vmMo.detachDisk(volumeDatastorePath, false); + } + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(volumeUuid); + return new CreateObjectAnswer(newVol); + } finally { + s_logger.info("Destroy dummy VM after volume creation"); + vmMo.detachAllDisks(); + vmMo.destroy(); + } + + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + this.hostService.invalidateServiceContext(null); + } + + String msg = "CreateCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new CreateObjectAnswer(e.toString()); + } + } + + @Override + public Answer createSnapshot(CreateObjectCommand cmd) { + // snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake + // a success return here + String snapshotUUID = UUID.randomUUID().toString(); + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); + newSnapshot.setPath(snapshotUUID); + return new CreateObjectAnswer(newSnapshot); + } + + @Override + public Answer deleteVolume(DeleteCommand cmd) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource DestroyCommand: " + _gson.toJson(cmd)); + } + + /* + * DestroyCommand content example + * + * {"volume": {"id":5,"name":"Volume1", "mountPoint":"/export/home/kelven/vmware-test/primary", + * "path":"6bb8762f-c34c-453c-8e03-26cc246ceec4", "size":0,"type":"DATADISK","resourceType": + * "STORAGE_POOL","storagePoolType":"NetworkFilesystem", "poolId":0,"deviceId":0 } } + * + * {"volume": {"id":1, "name":"i-2-1-KY-ROOT", "mountPoint":"/export/home/kelven/vmware-test/primary", + * "path":"i-2-1-KY-ROOT","size":0,"type":"ROOT", "resourceType":"STORAGE_POOL", "storagePoolType":"NetworkFilesystem", + * "poolId":0,"deviceId":0 } } + */ + + try { + VmwareContext context = this.hostService.getServiceContext(null); + VmwareHypervisorHost hyperHost = this.hostService.getHyperHost(context, null); + VolumeObjectTO vol = (VolumeObjectTO)cmd.getData(); + PrimaryDataStoreTO store = (PrimaryDataStoreTO)vol.getDataStore(); + + ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, store.getUuid()); + if (morDs == null) { + String msg = "Unable to find datastore based on volume mount point " + store.getPath(); + s_logger.error(msg); + throw new Exception(msg); + } + + DatastoreMO dsMo = new DatastoreMO(context, morDs); + + ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter(); + ManagedObjectReference morCluster = hyperHost.getHyperHostCluster(); + ClusterMO clusterMo = new ClusterMO(context, morCluster); + + if (vol.getVolumeType() == Volume.Type.ROOT) { + String vmName = vol.getVmName(); + if (vmName != null) { + VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vmName); + if (vmMo != null) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy root volume and VM itself. vmName " + vmName); + } + + HostMO hostMo = vmMo.getRunningHost(); + List networks = vmMo.getNetworksWithDetails(); + + // tear down all devices first before we destroy the VM to avoid accidently delete disk backing files + if (this.resource.getVmState(vmMo) != State.Stopped) + vmMo.safePowerOff(_shutdown_waitMs); + vmMo.tearDownDevices(new Class[] { VirtualDisk.class, VirtualEthernetCard.class }); + vmMo.destroy(); + + for (NetworkDetails netDetails : networks) { + if (netDetails.getGCTag() != null && netDetails.getGCTag().equalsIgnoreCase("true")) { + if (netDetails.getVMMorsOnNetwork() == null || netDetails.getVMMorsOnNetwork().length == 1) { + this.resource.cleanupNetwork(hostMo, netDetails); + } + } + } + } + + if (s_logger.isInfoEnabled()) + s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk"); + dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); + + // root volume may be created via linked-clone, delete the delta disk as well + if (_fullCloneFlag) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-flat.vmdk"); + } + dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true); + } else { + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-delta.vmdk"); + } + dsMo.deleteFile(vol.getPath() + "-delta.vmdk", morDc, true); + } + return new Answer(cmd, true, "Success"); + } + + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy root volume directly from datastore"); + } + } else { + // evitTemplate will be converted into DestroyCommand, test if we are running in this case + VirtualMachineMO vmMo = clusterMo.findVmOnHyperHost(vol.getPath()); + if (vmMo != null) { + if (s_logger.isInfoEnabled()) + s_logger.info("Destroy template volume " + vol.getPath()); + + vmMo.destroy(); + return new Answer(cmd, true, "Success"); + } + } + + String chainInfo = vol.getChainInfo(); + if (chainInfo != null && !chainInfo.isEmpty()) { + s_logger.info("Destroy volume by chain info: " + chainInfo); + String[] diskChain = _gson.fromJson(chainInfo, String[].class); + + if (diskChain != null && diskChain.length > 0) { + for (String backingName : diskChain) { + if (s_logger.isInfoEnabled()) { + s_logger.info("Delete volume backing file: " + backingName); + } + dsMo.deleteFile(backingName, morDc, true); + } + } else { + if (s_logger.isInfoEnabled()) { + s_logger.info("Empty disk chain info, fall back to try to delete by original backing file name"); + } + dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); + + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-flat.vmdk"); + } + dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true); + } + } else { + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy volume by original name: " + vol.getPath() + ".vmdk"); + } + dsMo.deleteFile(vol.getPath() + ".vmdk", morDc, true); + + if (s_logger.isInfoEnabled()) { + s_logger.info("Destroy volume by derived name: " + vol.getPath() + "-flat.vmdk"); + } + dsMo.deleteFile(vol.getPath() + "-flat.vmdk", morDc, true); + } + + return new Answer(cmd, true, "Success"); + } catch (Throwable e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + this.hostService.invalidateServiceContext(null); + } + + String msg = "DestroyCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg, e); + return new Answer(cmd, false, msg); + } + } +} diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c88a7462f8f..701adbe3a52 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -58,6 +58,8 @@ import com.cloud.agent.api.to.*; import com.cloud.network.rules.FirewallRule; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.w3c.dom.Document; @@ -234,6 +236,8 @@ import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; +import com.cloud.storage.resource.StorageSubsystemCommandHandler; +import com.cloud.storage.resource.StorageSubsystemCommandHandlerBase; import com.cloud.storage.template.TemplateProp; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.utils.NumbersUtil; @@ -334,7 +338,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected boolean _canBridgeFirewall = false; protected boolean _isOvs = false; protected List _tmpDom0Vif = new ArrayList(); - protected XenServerStorageResource storageResource; + protected StorageSubsystemCommandHandler storageHandler; protected int _maxNics = 7; public enum SRType { @@ -594,7 +598,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } else if (clazz == CheckS2SVpnConnectionsCommand.class) { return execute((CheckS2SVpnConnectionsCommand) cmd); } else if (cmd instanceof StorageSubSystemCommand) { - return this.storageResource.handleStorageCommands((StorageSubSystemCommand)cmd); + return this.storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else if (clazz == CreateVMSnapshotCommand.class) { return execute((CreateVMSnapshotCommand)cmd); } else if (clazz == DeleteVMSnapshotCommand.class) { @@ -1089,31 +1093,42 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } } - protected VDI mount(Connection conn, String vmName, VolumeTO volume) throws XmlRpcException, XenAPIException { - if (volume.getType() == Volume.Type.ISO) { - String isopath = volume.getPath(); - if (isopath == null) { + protected VDI mount(Connection conn, String vmName, DiskTO volume) throws XmlRpcException, XenAPIException { + DataTO data = volume.getData(); + Volume.Type type = volume.getType(); + if (type == Volume.Type.ISO) { + TemplateObjectTO iso = (TemplateObjectTO)data; + DataStoreTO store = iso.getDataStore(); + + if (store == null) { + //It's a fake iso return null; } - if (isopath.startsWith("xs-tools")) { + + //corer case, xenserver pv driver iso + String templateName = iso.getName(); + if (templateName.startsWith("xs-tools")) { try { - Set vdis = VDI.getByNameLabel(conn, isopath); + Set vdis = VDI.getByNameLabel(conn, templateName); if (vdis.isEmpty()) { - throw new CloudRuntimeException("Could not find ISO with URL: " + isopath); + throw new CloudRuntimeException("Could not find ISO with URL: " + templateName); } return vdis.iterator().next(); - } catch (XenAPIException e) { - throw new CloudRuntimeException("Unable to get pv iso: " + isopath + " due to " + e.toString()); + throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString()); } catch (Exception e) { - throw new CloudRuntimeException("Unable to get pv iso: " + isopath + " due to " + e.toString()); + throw new CloudRuntimeException("Unable to get pv iso: " + templateName + " due to " + e.toString()); } } + + if (!(store instanceof NfsTO)) { + throw new CloudRuntimeException("only support mount iso on nfs"); + } + NfsTO nfsStore = (NfsTO)store; + String isoPath = nfsStore.getUrl() + File.separator + iso.getPath(); + int index = isoPath.lastIndexOf("/"); - - int index = isopath.lastIndexOf("/"); - - String mountpoint = isopath.substring(0, index); + String mountpoint = isoPath.substring(0, index); URI uri; try { uri = new URI(mountpoint); @@ -1122,20 +1137,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } SR isoSr = createIsoSRbyURI(conn, uri, vmName, false); - String isoname = isopath.substring(index + 1); + String isoname = isoPath.substring(index + 1); VDI isoVdi = getVDIbyLocationandSR(conn, isoname, isoSr); if (isoVdi == null) { - throw new CloudRuntimeException("Unable to find ISO " + volume.getPath()); + throw new CloudRuntimeException("Unable to find ISO " + isoPath); } return isoVdi; } else { - return VDI.getByUuid(conn, volume.getPath()); + VolumeObjectTO vol = (VolumeObjectTO)data; + return VDI.getByUuid(conn,vol.getPath()); } } - protected VBD createVbd(Connection conn, VolumeTO volume, String vmName, VM vm, BootloaderType bootLoaderType) throws XmlRpcException, XenAPIException { + protected VBD createVbd(Connection conn, DiskTO volume, String vmName, VM vm, BootloaderType bootLoaderType) throws XmlRpcException, XenAPIException { Volume.Type type = volume.getType(); VDI vdi = mount(conn, vmName, volume); @@ -1153,7 +1169,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vbdr.bootable = true; } - vbdr.userdevice = Long.toString(volume.getDeviceId()); + vbdr.userdevice = Long.toString(volume.getDiskSeq()); if (volume.getType() == Volume.Type.ISO) { vbdr.mode = Types.VbdMode.RO; vbdr.type = Types.VbdType.CD; @@ -1246,12 +1262,17 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) { if (vmSpec.getBootloader() == BootloaderType.CD) { - VolumeTO [] disks = vmSpec.getDisks(); - for (VolumeTO disk : disks) { - if (disk.getType() == Volume.Type.ISO && disk.getOsType() != null) { - String isoGuestOsName = getGuestOsType(disk.getOsType(), vmSpec.getBootloader() == BootloaderType.CD); - if (!isoGuestOsName.equals(guestOsTypeName)) { - vmSpec.setBootloader(BootloaderType.PyGrub); + DiskTO [] disks = vmSpec.getDisks(); + for (DiskTO disk : disks) { + Volume.Type type = disk.getType(); + if (type == Volume.Type.ISO) { + TemplateObjectTO tmpl = (TemplateObjectTO)disk.getData(); + String osType = tmpl.getGuestOsType(); + if (tmpl.getFormat() == ImageFormat.ISO && osType != null ) { + String isoGuestOsName = getGuestOsType(osType, vmSpec.getBootloader() == BootloaderType.CD); + if (!isoGuestOsName.equals(guestOsTypeName)) { + vmSpec.setBootloader(BootloaderType.PyGrub); + } } } } @@ -1496,7 +1517,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Host host = Host.getByUuid(conn, _host.uuid); vm = createVmFromTemplate(conn, vmSpec, host); - for (VolumeTO disk : vmSpec.getDisks()) { + for (DiskTO disk : vmSpec.getDisks()) { createVbd(conn, disk, vmName, vm, vmSpec.getBootloader()); } @@ -5774,13 +5795,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe CheckXenHostInfo(); - this.storageResource = getStorageResource(); + this.storageHandler = getStorageHandler(); return true; } - protected XenServerStorageResource getStorageResource() { - return new XenServerStorageResource(this); + protected StorageSubsystemCommandHandler getStorageHandler() { + XenServerStorageProcessor processor = new XenServerStorageProcessor(this); + return new StorageSubsystemCommandHandlerBase(processor); } private void CheckXenHostInfo() throws ConfigurationException { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java index d64e17337a1..6ce3837b89c 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java @@ -26,11 +26,14 @@ import java.util.Map; import java.util.Set; import javax.ejb.Local; + +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.FenceAnswer; import com.cloud.agent.api.FenceCommand; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.resource.ServerResource; @@ -194,13 +197,17 @@ public class XenServer56FP1Resource extends XenServer56Resource { if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) { if (vmSpec.getBootloader() == BootloaderType.CD) { - VolumeTO[] disks = vmSpec.getDisks(); - for (VolumeTO disk : disks) { - if (disk.getType() == Volume.Type.ISO && disk.getOsType() != null) { - String isoGuestOsName = getGuestOsType(disk.getOsType(), vmSpec.getBootloader() == BootloaderType.CD); - if (!isoGuestOsName.equals(guestOsTypeName)) { - vmSpec.setBootloader(BootloaderType.PyGrub); - } + DiskTO[] disks = vmSpec.getDisks(); + for (DiskTO disk : disks) { + if (disk.getType() == Volume.Type.ISO ) { + TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); + String osType = iso.getGuestOsType(); + if (osType != null) { + String isoGuestOsName = getGuestOsType(osType, vmSpec.getBootloader() == BootloaderType.CD); + if (!isoGuestOsName.equals(guestOsTypeName)) { + vmSpec.setBootloader(BootloaderType.PyGrub); + } + } } } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java similarity index 77% rename from plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java rename to plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 8b27efec8c0..727c3f4b082 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -22,13 +22,9 @@ import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; -import java.io.BufferedOutputStream; import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URI; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -38,89 +34,315 @@ import java.util.Map; import java.util.Set; import java.util.UUID; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; +import org.apache.cloudstack.storage.command.AttachAnswer; +import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreAnswer; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.DeleteCommand; -import org.apache.cloudstack.storage.command.StorageSubSystemCommand; +import org.apache.cloudstack.storage.command.DettachAnswer; +import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.datastore.protocol.DataStoreProtocol; -import org.apache.cloudstack.storage.to.ImageStoreTO; import org.apache.cloudstack.storage.to.PrimaryDataStoreTO; import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.agent.api.Command; -import com.cloud.agent.api.ManageSnapshotAnswer; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; +import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.SwiftTO; -import com.cloud.agent.api.to.VolumeTO; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; -import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.resource.StorageProcessor; import com.cloud.utils.S3Utils; import com.cloud.utils.StringUtils; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.DecodedDataStore; import com.cloud.utils.storage.encoding.Decoder; -import com.cloud.vm.DiskProfile; import com.xensource.xenapi.Connection; import com.xensource.xenapi.Host; import com.xensource.xenapi.PBD; +import com.xensource.xenapi.Pool; import com.xensource.xenapi.SR; import com.xensource.xenapi.Types; import com.xensource.xenapi.Types.BadServerResponse; import com.xensource.xenapi.Types.XenAPIException; +import com.xensource.xenapi.VBD; import com.xensource.xenapi.VDI; +import com.xensource.xenapi.VM; +import com.xensource.xenapi.VMGuestMetrics; -public class XenServerStorageResource { - private static final Logger s_logger = Logger.getLogger(XenServerStorageResource.class); +public class XenServerStorageProcessor implements StorageProcessor { + private static final Logger s_logger = Logger.getLogger(XenServerStorageProcessor.class); protected CitrixResourceBase hypervisorResource; - public XenServerStorageResource(CitrixResourceBase resource) { + public XenServerStorageProcessor(CitrixResourceBase resource) { this.hypervisorResource = resource; } + + @Override + public AttachAnswer attachIso(AttachCommand cmd) { + DiskTO disk = cmd.getDisk(); + DataTO data = disk.getData(); + DataStoreTO store = data.getDataStore(); - public Answer handleStorageCommands(StorageSubSystemCommand command) { - if (command instanceof CopyCommand) { - return this.execute((CopyCommand)command); - } else if (command instanceof AttachPrimaryDataStoreCmd) { - return this.execute((AttachPrimaryDataStoreCmd)command); - } else if (command instanceof CreatePrimaryDataStoreCmd) { - return execute((CreatePrimaryDataStoreCmd) command); - } else if (command instanceof CreateObjectCommand) { - return execute((CreateObjectCommand) command); - } else if (command instanceof DeleteCommand) { - return execute((DeleteCommand)command); + if (!(store instanceof NfsTO)) { + s_logger.debug("Can't attach a iso which is not created on nfs: "); + return new AttachAnswer("Can't attach a iso which is not created on nfs: "); + } + NfsTO nfsStore = (NfsTO)store; + String isoURL = nfsStore.getUrl() + File.separator + data.getPath(); + + String vmName = cmd.getVmName(); + try { + Connection conn = this.hypervisorResource.getConnection(); + + VBD isoVBD = null; + + // Find the VM + VM vm = this.hypervisorResource.getVM(conn, vmName); + // Find the ISO VDI + VDI isoVDI = this.hypervisorResource.getIsoVDIByURL(conn, vmName, isoURL); + + // Find the VM's CD-ROM VBD + Set vbds = vm.getVBDs(conn); + for (VBD vbd : vbds) { + String userDevice = vbd.getUserdevice(conn); + Types.VbdType type = vbd.getType(conn); + + if (userDevice.equals("3") && type == Types.VbdType.CD) { + isoVBD = vbd; + break; + } + } + + if (isoVBD == null) { + throw new CloudRuntimeException("Unable to find CD-ROM VBD for VM: " + vmName); + } else { + // If an ISO is already inserted, eject it + if (isoVBD.getEmpty(conn) == false) { + isoVBD.eject(conn); + } + + // Insert the new ISO + isoVBD.insert(conn, isoVDI); + } + + return new AttachAnswer(disk); + + } catch (XenAPIException e) { + s_logger.warn("Failed to attach iso" + ": " + e.toString(), e); + return new AttachAnswer(e.toString()); + } catch (Exception e) { + s_logger.warn("Failed to attach iso" + ": " + e.toString(), e); + return new AttachAnswer(e.toString()); } - return new Answer((Command)command, false, "not implemented yet"); } + + @Override + public AttachAnswer attachVolume(AttachCommand cmd) { + String vmName = cmd.getVmName(); + DiskTO disk = cmd.getDisk(); + DataTO data = disk.getData(); + + try { + Connection conn = this.hypervisorResource.getConnection(); + // Look up the VDI + VDI vdi = this.hypervisorResource.mount(conn, null, null, data.getPath()); + // Look up the VM + VM vm = this.hypervisorResource.getVM(conn, vmName); + /* For HVM guest, if no pv driver installed, no attach/detach */ + boolean isHVM; + if (vm.getPVBootloader(conn).equalsIgnoreCase("")) { + isHVM = true; + } else { + isHVM = false; + } + VMGuestMetrics vgm = vm.getGuestMetrics(conn); + boolean pvDrvInstalled = false; + if (!this.hypervisorResource.isRefNull(vgm) && vgm.getPVDriversUpToDate(conn)) { + pvDrvInstalled = true; + } + if (isHVM && !pvDrvInstalled) { + s_logger.warn(": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected"); + return new AttachAnswer("You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); + } + + // Figure out the disk number to attach the VM to + String diskNumber = null; + Long deviceId = disk.getDiskSeq(); + if( deviceId != null ) { + if( deviceId.longValue() == 3 ) { + String msg = "Device 3 is reserved for CD-ROM, choose other device"; + return new AttachAnswer(msg); + } + if(this.hypervisorResource.isDeviceUsed(conn, vm, deviceId)) { + String msg = "Device " + deviceId + " is used in VM " + vmName; + return new AttachAnswer(msg); + } + diskNumber = deviceId.toString(); + } else { + diskNumber = this.hypervisorResource.getUnusedDeviceNum(conn, vm); + } + // Create a new VBD + VBD.Record vbdr = new VBD.Record(); + vbdr.VM = vm; + vbdr.VDI = vdi; + vbdr.bootable = false; + vbdr.userdevice = diskNumber; + vbdr.mode = Types.VbdMode.RW; + vbdr.type = Types.VbdType.DISK; + vbdr.unpluggable = true; + VBD vbd = VBD.create(conn, vbdr); + + // Attach the VBD to the VM + vbd.plug(conn); + + // Update the VDI's label to include the VM name + vdi.setNameLabel(conn, vmName + "-DATA"); + DiskTO newDisk = new DiskTO(disk.getData(), Long.parseLong(diskNumber), disk.getType()); + return new AttachAnswer(newDisk); + + } catch (XenAPIException e) { + String msg = "Failed to attach volume" + " for uuid: " + data.getPath() + " due to " + e.toString(); + s_logger.warn(msg, e); + return new AttachAnswer(msg); + } catch (Exception e) { + String msg = "Failed to attach volume" + " for uuid: " + data.getPath() + " due to " + e.getMessage(); + s_logger.warn(msg, e); + return new AttachAnswer(msg); + } + } + + @Override + public Answer dettachIso(DettachCommand cmd) { + DiskTO disk = cmd.getDisk(); + DataTO data = disk.getData(); + DataStoreTO store = data.getDataStore(); + + if (!(store instanceof NfsTO)) { + s_logger.debug("Can't attach a iso which is not created on nfs: "); + return new DettachAnswer("Can't attach a iso which is not created on nfs: "); + } + NfsTO nfsStore = (NfsTO)store; + String isoURL = nfsStore.getUrl() + File.separator + data.getPath(); + + try { + Connection conn = this.hypervisorResource.getConnection(); + // Find the VM + VM vm = this.hypervisorResource.getVM(conn, cmd.getVmName()); + String vmUUID = vm.getUuid(conn); + + // Find the ISO VDI + VDI isoVDI = this.hypervisorResource.getIsoVDIByURL(conn, cmd.getVmName(), isoURL); + + SR sr = isoVDI.getSR(conn); + + // Look up all VBDs for this VDI + Set vbds = isoVDI.getVBDs(conn); + + // Iterate through VBDs, and if the VBD belongs the VM, eject + // the ISO from it + for (VBD vbd : vbds) { + VM vbdVM = vbd.getVM(conn); + String vbdVmUUID = vbdVM.getUuid(conn); + + if (vbdVmUUID.equals(vmUUID)) { + // If an ISO is already inserted, eject it + if (!vbd.getEmpty(conn)) { + vbd.eject(conn); + } + break; + } + } + + if (!sr.getNameLabel(conn).startsWith("XenServer Tools")) { + this.hypervisorResource.removeSR(conn, sr); + } + + return new DettachAnswer(disk); + } catch (XenAPIException e) { + String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.toString(); + s_logger.warn(msg, e); + return new DettachAnswer(msg); + } catch (Exception e) { + String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.getMessage(); + s_logger.warn(msg, e); + return new DettachAnswer(msg); + } + } + + + @Override + public Answer dettachVolume(DettachCommand cmd) { + String vmName = cmd.getVmName(); + DiskTO disk = cmd.getDisk(); + DataTO data = disk.getData(); + try { + Connection conn = this.hypervisorResource.getConnection(); + // Look up the VDI + VDI vdi = this.hypervisorResource.mount(conn, null, null, data.getPath()); + // Look up the VM + VM vm = this.hypervisorResource.getVM(conn, vmName); + /* For HVM guest, if no pv driver installed, no attach/detach */ + boolean isHVM; + if (vm.getPVBootloader(conn).equalsIgnoreCase("")) { + isHVM = true; + } else { + isHVM = false; + } + VMGuestMetrics vgm = vm.getGuestMetrics(conn); + boolean pvDrvInstalled = false; + if (!this.hypervisorResource.isRefNull(vgm) && vgm.getPVDriversUpToDate(conn)) { + pvDrvInstalled = true; + } + if (isHVM && !pvDrvInstalled) { + s_logger.warn(": You attempted an operation on a VM which requires PV drivers to be installed but the drivers were not detected"); + return new DettachAnswer("You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); + } + + + // Look up all VBDs for this VDI + Set vbds = vdi.getVBDs(conn); + + // Detach each VBD from its VM, and then destroy it + for (VBD vbd : vbds) { + VBD.Record vbdr = vbd.getRecord(conn); + + if (vbdr.currentlyAttached) { + vbd.unplug(conn); + } + + vbd.destroy(conn); + } + + // Update the VDI's label to be "detached" + vdi.setNameLabel(conn, "detached"); + + this.hypervisorResource.umount(conn, vdi); + + return new DettachAnswer(disk); + } catch(Exception e) { + s_logger.warn("Failed dettach volume: " + data.getPath()); + return new DettachAnswer("Failed dettach volume: " + data.getPath() + ", due to " + e.toString()); + } + } + protected SR getSRByNameLabel(Connection conn, String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException { Set srs = SR.getByNameLabel(conn, nameLabel); @@ -146,26 +368,10 @@ public class XenServerStorageResource { vdi.destroy(conn); } - private Map getParameters(URI uri) { - String parameters = uri.getQuery(); - Map params = new HashMap(); - List paraLists = Arrays.asList(parameters.split("&")); - for (String para : paraLists) { - String[] pair = para.split("="); - params.put(pair[0], pair[1]); - } - return params; - } - - protected CreateObjectAnswer getTemplateSize(CreateObjectCommand cmd, String templateUrl) { - /*Connection conn = hypervisorResource.getConnection(); - long size = this.getTemplateSize(conn, templateUrl); - return new CreateObjectAnswer(cmd, templateUrl, size);*/ - return null; - } - - protected CreateObjectAnswer createSnapshot(SnapshotObjectTO snapshotTO) { + @Override + public Answer createSnapshot(CreateObjectCommand cmd) { Connection conn = hypervisorResource.getConnection(); + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)cmd.getData(); long snapshotId = snapshotTO.getId(); String snapshotName = snapshotTO.getName(); String details = "create snapshot operation Failed for snapshotId: " + snapshotId; @@ -211,22 +417,10 @@ public class XenServerStorageResource { return new CreateObjectAnswer(details); } - protected CreateObjectAnswer execute(CreateObjectCommand cmd) { - DataTO data = cmd.getData(); - try { - if (data.getObjectType() == DataObjectType.VOLUME) { - return createVolume(data); - } else if (data.getObjectType() == DataObjectType.SNAPSHOT) { - return createSnapshot((SnapshotObjectTO)data); - } - return new CreateObjectAnswer("not supported type"); - } catch (Exception e) { - s_logger.debug("Failed to create object: " + data.getObjectType() + ": " + e.toString()); - return new CreateObjectAnswer(e.toString()); - } - } - protected Answer deleteVolume(VolumeObjectTO volume) { + @Override + public Answer deleteVolume(DeleteCommand cmd) { + DataTO volume = cmd.getData(); Connection conn = hypervisorResource.getConnection(); String errorMsg = null; try { @@ -246,46 +440,12 @@ public class XenServerStorageResource { return new Answer(null, false, errorMsg); } - protected Answer execute(DeleteCommand cmd) { - DataTO data = cmd.getData(); - Answer answer = null; - if (data.getObjectType() == DataObjectType.VOLUME) { - answer = deleteVolume((VolumeObjectTO)data); - } else { - answer = new Answer(cmd, false, "unsupported type"); - } - - return answer; - } - - /* protected Answer execute(CreateVolumeFromBaseImageCommand cmd) { - VolumeObjectTO volume = cmd.getVolume(); - ImageOnPrimayDataStoreTO baseImage = cmd.getImage(); - Connection conn = hypervisorResource.getConnection(); - - try { - VDI baseVdi = VDI.getByUuid(conn, baseImage.getPathOnPrimaryDataStore()); - VDI newVol = baseVdi.createClone(conn, new HashMap()); - newVol.setNameLabel(conn, volume.getName()); - return new CreateObjectAnswer(cmd, newVol.getUuid(conn), newVol.getVirtualSize(conn)); - } catch (BadServerResponse e) { - return new Answer(cmd, false, e.toString()); - } catch (XenAPIException e) { - return new Answer(cmd, false, e.toString()); - } catch (XmlRpcException e) { - return new Answer(cmd, false, e.toString()); - } - }*/ - - protected SR getNfsSR(Connection conn, DecodedDataStore store) { + protected SR getNfsSR(Connection conn, StorageFilerTO pool) { Map deviceConfig = new HashMap(); - - String uuid = store.getUuid(); try { - String server = store.getServer(); - String serverpath = store.getPath(); - + String server = pool.getHost(); + String serverpath = pool.getPath(); serverpath = serverpath.replace("//", "/"); Set srs = SR.getAll(conn); for (SR sr : srs) { @@ -316,25 +476,25 @@ public class XenServerStorageResource { if (server.equals(dc.get("server")) && serverpath.equals(dc.get("serverpath"))) { throw new CloudRuntimeException("There is a SR using the same configuration server:" + dc.get("server") + ", serverpath:" - + dc.get("serverpath") + " for pool " + uuid + "on host:" + hypervisorResource.getHost().uuid); + + dc.get("serverpath") + " for pool " + pool.getUuid() + "on host:" + hypervisorResource.getHost().uuid); } } deviceConfig.put("server", server); deviceConfig.put("serverpath", serverpath); Host host = Host.getByUuid(conn, hypervisorResource.getHost().uuid); - SR sr = SR.create(conn, host, deviceConfig, new Long(0), uuid, uuid, SRType.NFS.toString(), "user", true, + SR sr = SR.create(conn, host, deviceConfig, new Long(0), pool.getUuid(), Long.toString(pool.getId()), SRType.NFS.toString(), "user", true, new HashMap()); sr.scan(conn); return sr; } catch (XenAPIException e) { - throw new CloudRuntimeException("Unable to create NFS SR " + uuid, e); + throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); } catch (XmlRpcException e) { - throw new CloudRuntimeException("Unable to create NFS SR " + uuid, e); + throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); } } - /* - protected SR getIscsiSR(Connection conn, PrimaryDataStoreTO pool) { + + protected SR getIscsiSR(Connection conn, StorageFilerTO pool) { synchronized (pool.getUuid().intern()) { Map deviceConfig = new HashMap(); try { @@ -379,13 +539,13 @@ public class XenServerStorageResource { } if (target.equals(dc.get("target")) && targetiqn.equals(dc.get("targetIQN")) && lunid.equals(dc.get("lunid"))) { throw new CloudRuntimeException("There is a SR using the same configuration target:" + dc.get("target") + ", targetIQN:" - + dc.get("targetIQN") + ", lunid:" + dc.get("lunid") + " for pool " + pool.getUuid() + "on host:" + _host.uuid); + + dc.get("targetIQN") + ", lunid:" + dc.get("lunid") + " for pool " + pool.getUuid() + "on host:" + this.hypervisorResource.getHost().uuid); } } deviceConfig.put("target", target); deviceConfig.put("targetIQN", targetiqn); - Host host = Host.getByUuid(conn, _host.uuid); + Host host = Host.getByUuid(conn, this.hypervisorResource.getHost().uuid); Map smConfig = new HashMap(); String type = SRType.LVMOISCSI.toString(); String poolId = Long.toString(pool.getId()); @@ -456,99 +616,24 @@ public class XenServerStorageResource { throw new CloudRuntimeException(msg, e); } } - }*/ - - protected Answer execute(CreatePrimaryDataStoreCmd cmd) { - Connection conn = hypervisorResource.getConnection(); - String storeUrl = cmd.getDataStore(); - + } + protected Answer execute(CreateStoragePoolCommand cmd) { + Connection conn = this.hypervisorResource.getConnection(); + StorageFilerTO pool = cmd.getPool(); try { - DecodedDataObject obj = Decoder.decode(storeUrl); - DecodedDataStore store = obj.getStore(); - - if (store.getScheme().equalsIgnoreCase("nfs")) { - SR sr = getNfsSR(conn, store); - } else if (store.getScheme().equalsIgnoreCase("iscsi")) { - //getIscsiSR(conn, dataStore); - } else if (store.getScheme().equalsIgnoreCase("presetup")) { + if (pool.getType() == StoragePoolType.NetworkFilesystem) { + getNfsSR(conn, pool); + } else if (pool.getType() == StoragePoolType.IscsiLUN) { + getIscsiSR(conn, pool); + } else if (pool.getType() == StoragePoolType.PreSetup) { } else { - return new Answer(cmd, false, "The pool type: " + store.getScheme() + " is not supported."); + return new Answer(cmd, false, "The pool type: " + pool.getType().name() + " is not supported."); } return new Answer(cmd, true, "success"); } catch (Exception e) { - // String msg = "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + _host.uuid + " pool: " + pool.getHost() + pool.getPath(); - //s_logger.warn(msg, e); - return new Answer(cmd, false, null); - } - } - - private long getTemplateSize(Connection conn, String url) { - String size = hypervisorResource.callHostPlugin(conn, "storagePlugin", "getTemplateSize", "srcUrl", url); - if (size.equalsIgnoreCase("") || size == null) { - throw new CloudRuntimeException("Can't get template size"); - } - - try { - return Long.parseLong(size); - } catch (NumberFormatException e) { - throw new CloudRuntimeException("Failed to get template lenght", e); - } - - /* - HttpHead method = new HttpHead(url); - DefaultHttpClient client = new DefaultHttpClient(); - try { - HttpResponse response = client.execute(method); - Header header = response.getFirstHeader("Content-Length"); - if (header == null) { - throw new CloudRuntimeException("Can't get content-lenght header from :" + url); - } - Long length = Long.parseLong(header.getValue()); - return length; - } catch (HttpException e) { - throw new CloudRuntimeException("Failed to get template lenght", e); - } catch (IOException e) { - throw new CloudRuntimeException("Failed to get template lenght", e); - } catch (NumberFormatException e) { - throw new CloudRuntimeException("Failed to get template lenght", e); - }*/ - } - - private void downloadHttpToLocalFile(String destFilePath, String url) { - File destFile = new File(destFilePath); - if (!destFile.exists()) { - throw new CloudRuntimeException("dest file doesn't exist: " + destFilePath); - } - - DefaultHttpClient client = new DefaultHttpClient(); - HttpGet getMethod = new HttpGet(url); - HttpResponse response; - BufferedOutputStream output = null; - long length = 0; - try { - response = client.execute(getMethod); - HttpEntity entity = response.getEntity(); - length = entity.getContentLength(); - output = new BufferedOutputStream(new FileOutputStream(destFile)); - entity.writeTo(output); - } catch (ClientProtocolException e) { - throw new CloudRuntimeException("Failed to download template", e); - } catch (IOException e) { - throw new CloudRuntimeException("Failed to download template", e); - } finally { - if (output != null) { - try { - output.close(); - } catch (IOException e) { - throw new CloudRuntimeException("Failed to download template", e); - } - } - } - - //double check the length - destFile = new File(destFilePath); - if (destFile.length() != length) { - throw new CloudRuntimeException("Download file length doesn't match: expected: " + length + ", actual: " + destFile.length()); + String msg = "Catch Exception " + e.getClass().getName() + ", create StoragePool failed due to " + e.toString() + " on host:" + this.hypervisorResource.getHost().uuid + " pool: " + pool.getHost() + pool.getPath(); + s_logger.warn(msg, e); + return new Answer(cmd, false, msg); } } @@ -721,7 +806,11 @@ public class XenServerStorageResource { return parentUuid; } - protected CopyCmdAnswer copyTemplateToPrimaryStorage(DataTO srcData, DataTO destData, int wait) { + @Override + public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); DataStoreTO srcStore = srcData.getDataStore(); try { if ((srcStore instanceof NfsTO) && (srcData.getObjectType() == DataObjectType.TEMPLATE)) { @@ -774,32 +863,42 @@ public class XenServerStorageResource { return new CopyCmdAnswer("not implemented yet"); } - protected CreateObjectAnswer createVolume(DataTO data) throws BadServerResponse, XenAPIException, XmlRpcException { - VolumeObjectTO volume = (VolumeObjectTO)data; + @Override + public Answer createVolume(CreateObjectCommand cmd) { + DataTO data = cmd.getData(); + VolumeObjectTO volume = (VolumeObjectTO)data; - Connection conn = hypervisorResource.getConnection(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)data.getDataStore(); - SR poolSr = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); - VDI.Record vdir = new VDI.Record(); - vdir.nameLabel = volume.getName(); - vdir.SR = poolSr; - vdir.type = Types.VdiType.USER; + try { + Connection conn = hypervisorResource.getConnection(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)data.getDataStore(); + SR poolSr = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); + VDI.Record vdir = new VDI.Record(); + vdir.nameLabel = volume.getName(); + vdir.SR = poolSr; + vdir.type = Types.VdiType.USER; - vdir.virtualSize = volume.getSize(); - VDI vdi; + vdir.virtualSize = volume.getSize(); + VDI vdi; - vdi = VDI.create(conn, vdir); - vdir = vdi.getRecord(conn); - VolumeObjectTO newVol = new VolumeObjectTO(); - newVol.setName(vdir.nameLabel); - newVol.setSize(vdir.virtualSize); - newVol.setPath(vdir.uuid); + vdi = VDI.create(conn, vdir); + vdir = vdi.getRecord(conn); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setName(vdir.nameLabel); + newVol.setSize(vdir.virtualSize); + newVol.setPath(vdir.uuid); - return new CreateObjectAnswer(newVol); + return new CreateObjectAnswer(newVol); + } catch (Exception e) { + s_logger.debug("create volume failed: " + e.toString()); + return new CreateObjectAnswer(e.toString()); + } } - protected CopyCmdAnswer cloneVolumeFromBaseTemplate(DataTO srcData, DataTO destData) { + @Override + public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { Connection conn = hypervisorResource.getConnection(); + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); VolumeObjectTO volume = (VolumeObjectTO)destData; VDI vdi = null; @@ -827,9 +926,12 @@ public class XenServerStorageResource { } } - - protected Answer copyVolumeFromImageCacheToPrimary(DataTO srcData, DataTO destData, int wait) { + @Override + public Answer copyVolumeFromImageCacheToPrimary(CopyCommand cmd) { Connection conn = hypervisorResource.getConnection(); + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); VolumeObjectTO srcVolume = (VolumeObjectTO)srcData; VolumeObjectTO destVolume = (VolumeObjectTO)destData; PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)destVolume.getDataStore(); @@ -858,10 +960,12 @@ public class XenServerStorageResource { return new CopyCmdAnswer("unsupported protocol"); } - protected Answer copyVolumeFromPrimaryToSecondary(DataTO srcData, DataTO destData, int wait) { + @Override + public Answer copyVolumeFromPrimaryToSecondary(CopyCommand cmd) { Connection conn = hypervisorResource.getConnection(); - VolumeObjectTO srcVolume = (VolumeObjectTO)srcData; - VolumeObjectTO destVolume = (VolumeObjectTO)destData; + VolumeObjectTO srcVolume = (VolumeObjectTO)cmd.getSrcTO(); + VolumeObjectTO destVolume = (VolumeObjectTO)cmd.getDestTO(); + int wait = cmd.getWait(); DataStoreTO destStore = destVolume.getDataStore(); if (destStore instanceof NfsTO) { @@ -1088,8 +1192,13 @@ public class XenServerStorageResource { return false; } - protected Answer backupSnasphot(DataTO srcData, DataTO destData, DataTO cacheData, int wait) { + @Override + public Answer backupSnasphot(CopyCommand cmd) { Connection conn = hypervisorResource.getConnection(); + DataTO srcData = cmd.getSrcTO(); + DataTO cacheData = cmd.getCacheTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)srcData.getDataStore(); String primaryStorageNameLabel = primaryStore.getUuid(); String secondaryStorageUrl = null; @@ -1220,11 +1329,13 @@ public class XenServerStorageResource { return new CopyCmdAnswer(details); } - protected CopyCmdAnswer createTemplateFromVolume(DataTO srcData, DataTO destData, int wait) { + @Override + public Answer createTemplateFromVolume(CopyCommand cmd) { Connection conn = this.hypervisorResource.getConnection(); - VolumeObjectTO volume = (VolumeObjectTO)srcData; - TemplateObjectTO template = (TemplateObjectTO)destData; - NfsTO destStore = (NfsTO)destData.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO)cmd.getSrcTO(); + TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO(); + NfsTO destStore = (NfsTO)cmd.getDestTO().getDataStore(); + int wait = cmd.getWait(); String secondaryStoragePoolURL = destStore.getUrl(); String volumeUUID = volume.getPath(); @@ -1290,38 +1401,4 @@ public class XenServerStorageResource { } return new CopyCmdAnswer(details); } - - protected Answer execute(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - DataStoreTO srcDataStore = srcData.getDataStore(); - DataStoreTO destDataStore = destData.getDataStore(); - DataObjectType srcType = srcData.getObjectType(); - DataObjectType destType = destData.getObjectType(); - DataStoreRole destRole = destDataStore.getRole(); - - boolean nfs = (srcDataStore instanceof NfsTO) ? true : false; - - if ((srcData.getObjectType() == DataObjectType.TEMPLATE) && (srcDataStore instanceof NfsTO) && (destData.getDataStore().getRole() == DataStoreRole.Primary)) { - //copy template to primary storage - return copyTemplateToPrimaryStorage(srcData, destData, cmd.getWait()); - } else if (srcData.getObjectType() == DataObjectType.TEMPLATE && srcDataStore.getRole() == DataStoreRole.Primary && destDataStore.getRole() == DataStoreRole.Primary) { - //clone template to a volume - return cloneVolumeFromBaseTemplate(srcData, destData); - } else if (srcData.getObjectType() == DataObjectType.VOLUME && (srcData.getDataStore().getRole() == DataStoreRole.ImageCache || srcDataStore.getRole() == DataStoreRole.Image)) { - //copy volume from image cache to primary - return copyVolumeFromImageCacheToPrimary(srcData, destData, cmd.getWait()); - } else if (srcData.getObjectType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary) { - if (destData.getObjectType() == DataObjectType.VOLUME) { - return copyVolumeFromPrimaryToSecondary(srcData, destData, cmd.getWait()); - } else if (destData.getObjectType() == DataObjectType.TEMPLATE) { - return createTemplateFromVolume(srcData, destData, cmd.getWait()); - } - } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) { - DataTO cacheData = cmd.getCacheTO(); - return backupSnasphot(srcData, destData, cacheData, cmd.getWait()); - } - - return new Answer(cmd, false, "not implemented yet"); - } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 1865068ac55..52f8d9cf45f 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -27,10 +27,8 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -53,7 +51,9 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 354151eaa3c..1992c5eda06 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -29,10 +29,8 @@ import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; @@ -57,7 +55,9 @@ import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.S3TO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index 72864c3513a..2c7ba1117b4 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -25,9 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -36,7 +34,9 @@ import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.image.ImageStoreDriver; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.storage.dao.VMTemplateDao; //http-read-only based image store diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 0eb3acfc6a3..82df043bb81 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -29,10 +29,8 @@ import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; @@ -56,7 +54,9 @@ import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 912a11ee66e..aad17691f47 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -25,9 +25,7 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; 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.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; @@ -50,7 +48,9 @@ import com.cloud.agent.api.storage.CreateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.dao.HostDao; diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index f530362896c..b3a83f797c3 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -25,7 +25,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; @@ -42,6 +41,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index 9b2334bb60e..eee9ba5e1d9 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -22,7 +22,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -30,6 +29,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index d77796da300..2300953e37f 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.inject.Inject; import com.cloud.agent.api.Command; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; @@ -101,7 +102,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis } to.setNics(nics); - to.setDisks(vmProfile.getDisks().toArray(new VolumeTO[vmProfile.getDisks().size()])); + to.setDisks(vmProfile.getDisks().toArray(new DataTO[vmProfile.getDisks().size()])); if(vmProfile.getTemplate().getBits() == 32) { to.setArch("i686"); diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 90b2366130e..17e0e0906b8 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -45,18 +45,22 @@ import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; 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.DataStoreProviderManager; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.AttachAnswer; +import org.apache.cloudstack.storage.command.AttachCommand; +import org.apache.cloudstack.storage.command.DettachAnswer; +import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -69,8 +73,8 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachVolumeAnswer; -import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.to.VolumeTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobExecutor; @@ -117,7 +121,6 @@ import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Event; import com.cloud.storage.Volume.Type; import com.cloud.storage.dao.DiskOfferingDao; @@ -168,7 +171,6 @@ import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -import com.cloud.vm.snapshot.VMSnapshot; import com.cloud.vm.snapshot.VMSnapshotVO; import com.cloud.vm.snapshot.dao.VMSnapshotDao; @@ -1514,7 +1516,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { String errorMsg = "Failed to attach volume: " + volume.getName() + " to VM: " + vm.getHostName(); boolean sendCommand = (vm.getState() == State.Running); - AttachVolumeAnswer answer = null; + AttachAnswer answer = null; Long hostId = vm.getHostId(); if (hostId == null) { hostId = vm.getLastHostId(); @@ -1526,16 +1528,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } if (sendCommand) { - StoragePoolVO volumePool = _storagePoolDao.findById(volume - .getPoolId()); - AttachVolumeCommand cmd = new AttachVolumeCommand(true, - vm.getInstanceName(), volume.getPoolType(), - volume.getFolder(), volume.getPath(), volume.getName(), - deviceId, volume.getChainInfo()); - cmd.setPoolUuid(volumePool.getUuid()); - + DataTO volTO = this.volFactory.getVolume(volume.getId()).getTO(); + DiskTO disk = new DiskTO(volTO, deviceId, volume.getVolumeType()); + AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName()); try { - answer = (AttachVolumeAnswer) _agentMgr.send(hostId, cmd); + answer = (AttachAnswer) _agentMgr.send(hostId, cmd); } catch (Exception e) { throw new CloudRuntimeException(errorMsg + " due to: " + e.getMessage()); @@ -1545,8 +1542,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (!sendCommand || (answer != null && answer.getResult())) { // Mark the volume as attached if (sendCommand) { + DiskTO disk = answer.getDisk(); _volsDao.attachVolume(volume.getId(), vm.getId(), - answer.getDeviceId()); + disk.getDiskSeq()); } else { _volsDao.attachVolume(volume.getId(), vm.getId(), deviceId); } @@ -1858,16 +1856,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { Answer answer = null; if (sendCommand) { - AttachVolumeCommand cmd = new AttachVolumeCommand(false, - vm.getInstanceName(), volume.getPoolType(), - volume.getFolder(), volume.getPath(), volume.getName(), - cmmd.getDeviceId() != null ? cmmd.getDeviceId() : volume - .getDeviceId(), volume.getChainInfo()); - - StoragePoolVO volumePool = _storagePoolDao.findById(volume - .getPoolId()); - cmd.setPoolUuid(volumePool.getUuid()); - + DataTO volTO = this.volFactory.getVolume(volume.getId()).getTO(); + DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getVolumeType()); + DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName()); try { answer = _agentMgr.send(vm.getHostId(), cmd); } catch (Exception e) { @@ -1879,12 +1870,6 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { if (!sendCommand || (answer != null && answer.getResult())) { // Mark the volume as detached _volsDao.detachVolume(volume.getId()); - if (answer != null && answer instanceof AttachVolumeAnswer) { - volume.setChainInfo(((AttachVolumeAnswer) answer) - .getChainInfo()); - _volsDao.update(volume.getId(), volume); - } - return _volsDao.findById(volumeId); } else { @@ -2097,22 +2082,17 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } for (VolumeVO vol : vols) { - PrimaryDataStoreInfo pool = (PrimaryDataStoreInfo)this.dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary); - vm.addDisk(new VolumeTO(vol, pool)); + DataTO volTO = this.volFactory.getVolume(vol.getId()).getTO(); + DiskTO disk = new DiskTO(volTO, vol.getDeviceId(), vol.getVolumeType()); + vm.addDisk(disk); } if (vm.getType() == VirtualMachine.Type.User) { UserVmVO userVM = (UserVmVO) vm.getVirtualMachine(); if (userVM.getIsoId() != null) { - Pair isoPathPair = this._tmpltMgr.getAbsoluteIsoPath( - userVM.getIsoId(), userVM.getDataCenterId()); - if (isoPathPair != null) { - String isoPath = isoPathPair.first(); - VolumeTO iso = new VolumeTO(vm.getId(), Volume.Type.ISO, - StoragePoolType.ISO, null, null, null, isoPath, 0, - null, null); - vm.addDisk(iso); - } + DataTO dataTO = this.tmplFactory.getTemplate(userVM.getIsoId(), DataStoreRole.Image, userVM.getDataCenterId()).getTO(); + DiskTO iso = new DiskTO(dataTO, 3L, Volume.Type.ISO); + vm.addDisk(iso); } } } @@ -2328,7 +2308,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { pool = (StoragePool)dataStoreMgr.getDataStore(result.second().getId(), DataStoreRole.Primary); vol = result.first(); } - vm.addDisk(new VolumeTO(vol, pool)); + DataTO volumeTO = this.volFactory.getVolume(vol.getId()).getTO(); + DiskTO disk = new DiskTO(volumeTO, vol.getDeviceId(), vol.getVolumeType()); + vm.addDisk(disk); } } diff --git a/server/src/com/cloud/storage/download/DownloadListener.java b/server/src/com/cloud/storage/download/DownloadListener.java index 001b45dc1c4..691d65548d7 100755 --- a/server/src/com/cloud/storage/download/DownloadListener.java +++ b/server/src/com/cloud/storage/download/DownloadListener.java @@ -26,7 +26,6 @@ import java.util.TimerTask; import javax.inject.Inject; 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; @@ -50,6 +49,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupRoutingCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; import com.cloud.host.Host; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 20cdce16c36..0bdd8c14f64 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -65,7 +65,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -79,8 +81,11 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; +import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.storage.DestroyCommand; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -1024,27 +1029,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } else if (vm.getState() != State.Running) { return true; } - String isoPath; - VMTemplateVO tmplt = this._tmpltDao.findById(isoId); + //FIXME: if it's s3, need to download into cache store + TemplateInfo tmplt = this._tmplFactory.getTemplate(isoId, DataStoreRole.Image, vm.getDataCenterId()); if (tmplt == null) { s_logger.warn("ISO: " + isoId + " does not exist"); return false; } - // Get the path of the ISO - Pair isoPathPair = null; - if (tmplt.getTemplateType() == TemplateType.PERHOST) { - isoPath = tmplt.getName(); - } else { - isoPathPair = getAbsoluteIsoPath(isoId, - vm.getDataCenterId()); - if (isoPathPair == null) { - s_logger.warn("Couldn't get absolute iso path"); - return false; - } else { - isoPath = isoPathPair.first(); - } - } - + String vmName = vm.getInstanceName(); HostVO host = _hostDao.findById(vm.getHostId()); @@ -1052,12 +1043,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.warn("Host: " + vm.getHostId() + " does not exist"); return false; } - AttachIsoCommand cmd = new AttachIsoCommand(vmName, isoPath, attach); - if (isoPathPair != null) { - cmd.setStoreUrl(isoPathPair.second()); + + DataTO isoTO = tmplt.getTO(); + DiskTO disk = new DiskTO(isoTO, null, Volume.Type.ISO); + Command cmd = null; + if (attach) { + cmd = new AttachCommand(disk, vmName); + } else { + cmd = new DettachCommand(disk, vmName); } Answer a = _agentMgr.easySend(vm.getHostId(), cmd); - return (a != null && a.getResult()); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 000430fca25..98aeaf2e612 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -42,7 +42,10 @@ import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd; import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity; import org.apache.cloudstack.engine.service.api.OrchestrationService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; @@ -58,6 +61,7 @@ import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.UnPlugNicAnswer; import com.cloud.agent.api.UnPlugNicCommand; import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; @@ -159,6 +163,7 @@ import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolStatus; @@ -373,6 +378,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use @Inject List plannerSelectors; + @Inject + TemplateDataFactory templateFactory; protected ScheduledExecutorService _executor = null; protected int _expungeInterval; @@ -2625,52 +2632,33 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use vm.setDetails(details); if (vm.getIsoId() != null) { - String isoPath = null; - - VirtualMachineTemplate template = _templateDao.findById(vm - .getIsoId()); + TemplateInfo template = templateFactory.getTemplate(vm.getIsoId(), DataStoreRole.Image, vm.getDataCenterId()); + if (template == null || template.getFormat() != ImageFormat.ISO) { throw new CloudRuntimeException( "Can not find ISO in vm_template table for id " + vm.getIsoId()); } - - Pair isoPathPair = this.templateMgr.getAbsoluteIsoPath( - template.getId(), vm.getDataCenterId()); - - if (template.getTemplateType() == TemplateType.PERHOST) { - isoPath = template.getName(); - } else { - if (isoPathPair == null) { - s_logger.warn("Couldn't get absolute iso path"); - return false; - } else { - isoPath = isoPathPair.first(); - } - } - + if (template.isBootable()) { profile.setBootLoaderType(BootloaderType.CD); } + GuestOSVO guestOS = _guestOSDao.findById(template.getGuestOSId()); String displayName = null; if (guestOS != null) { displayName = guestOS.getDisplayName(); } - VolumeTO iso = new VolumeTO(profile.getId(), Volume.Type.ISO, - StoragePoolType.ISO, null, template.getName(), null, - isoPath, 0, null, displayName); - - iso.setDeviceId(3); - profile.addDisk(iso); + + TemplateObjectTO iso = (TemplateObjectTO)template.getTO(); + iso.setGuestOsType(displayName); + DiskTO disk = new DiskTO(iso, 3L, Volume.Type.ISO); + profile.addDisk(disk); } else { - VirtualMachineTemplate template = profile.getTemplate(); - /* create a iso placeholder */ - VolumeTO iso = new VolumeTO(profile.getId(), Volume.Type.ISO, - StoragePoolType.ISO, null, template.getName(), null, null, - 0, null); - iso.setDeviceId(3); - profile.addDisk(iso); + TemplateObjectTO iso = new TemplateObjectTO(); + iso.setFormat(ImageFormat.ISO); + DiskTO disk = new DiskTO(iso, 3L, Volume.Type.ISO); + profile.addDisk(disk); } return true; diff --git a/server/src/com/cloud/vm/VirtualMachineProfileImpl.java b/server/src/com/cloud/vm/VirtualMachineProfileImpl.java index 24f44cb07ac..c4e8822c0d8 100644 --- a/server/src/com/cloud/vm/VirtualMachineProfileImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineProfileImpl.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Map; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.offering.ServiceOffering; @@ -46,7 +47,7 @@ public class VirtualMachineProfileImpl implements Virtua UserVmDetailVO _userVmDetails; Map _params; List _nics = new ArrayList(); - List _disks = new ArrayList(); + List _disks = new ArrayList(); StringBuilder _bootArgs = new StringBuilder(); Account _owner; BootloaderType _bootloader; @@ -141,7 +142,7 @@ public class VirtualMachineProfileImpl implements Virtua _nics = nics; } - public void setDisks(List disks) { + public void setDisks(List disks) { _disks = disks; } @@ -151,7 +152,7 @@ public class VirtualMachineProfileImpl implements Virtua } @Override - public List getDisks() { + public List getDisks() { return _disks; } @@ -161,7 +162,7 @@ public class VirtualMachineProfileImpl implements Virtua } @Override - public void addDisk(int index, VolumeTO disk) { + public void addDisk(int index, DiskTO disk) { _disks.add(index, disk); } @@ -210,7 +211,7 @@ public class VirtualMachineProfileImpl implements Virtua } @Override - public void addDisk(VolumeTO disk) { + public void addDisk(DiskTO disk) { _disks.add(disk); } From e444867e619e88a68af0a06974f63ed892e8d39d Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 10 May 2013 09:47:09 -0700 Subject: [PATCH 147/303] fix compile --- .../image/TemplateDataFactoryImpl.java | 11 -------- .../cloud/ovm/hypervisor/OvmResourceBase.java | 26 +++++++++++++++---- .../cloud/hypervisor/HypervisorGuruBase.java | 3 ++- tools/marvin/marvin/deployDataCenter.py | 5 ++-- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java index 09c79b22f98..52c79e6da6b 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java @@ -90,17 +90,6 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory { } return this.getTemplate(templateId, store); } - - @Override - public TemplateInfo getTemplate(long templateId, long zoneId) { - TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if (tmplStore != null) { - DataStore store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), DataStoreRole.Image); - return this.getTemplate(templateId, store); - } - return null; - } - @Override public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId) { diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index 7d8d90c7b61..61ac54e5523 100755 --- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -29,6 +29,8 @@ import java.util.concurrent.ConcurrentHashMap; import javax.naming.ConfigurationException; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; @@ -90,6 +92,10 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VirtualMachineTO; @@ -527,25 +533,35 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { } protected void createVbds(OvmVm.Details vm, VirtualMachineTO spec) throws URISyntaxException { - for (VolumeTO volume : spec.getDisks()) { + for (DiskTO volume : spec.getDisks()) { if (volume.getType() == Volume.Type.ROOT) { + VolumeObjectTO vol = (VolumeObjectTO)volume.getData(); OvmDisk.Details root = new OvmDisk.Details(); - root.path = volume.getPath(); + root.path = vol.getPath(); root.type = OvmDisk.WRITE; root.isIso = false; vm.rootDisk = root; } else if (volume.getType() == Volume.Type.ISO) { - if (volume.getPath() != null) { + DataTO isoTO = volume.getData(); + if (isoTO.getPath() != null) { + TemplateObjectTO template = (TemplateObjectTO)isoTO; + DataStoreTO store = template.getDataStore(); + if (!(store instanceof NfsTO)) { + throw new CloudRuntimeException("unsupported protocol"); + } + NfsTO nfsStore = (NfsTO)store; + String isoPath = nfsStore.getUrl() + File.separator + template.getPath(); OvmDisk.Details iso = new OvmDisk.Details(); - URI path = new URI(volume.getPath()); + URI path = new URI(isoPath); iso.path = path.getHost() + ":" + path.getPath(); iso.type = OvmDisk.READ; iso.isIso = true; vm.disks.add(iso); } } else if (volume.getType() == Volume.Type.DATADISK){ + OvmDisk.Details data = new OvmDisk.Details(); - data.path = volume.getPath(); + data.path = volume.getData().getPath(); data.type = OvmDisk.SHAREDWRITE; data.isIso = false; vm.disks.add(data); diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index 2300953e37f..e11aa50fd00 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; @@ -102,7 +103,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis } to.setNics(nics); - to.setDisks(vmProfile.getDisks().toArray(new DataTO[vmProfile.getDisks().size()])); + to.setDisks(vmProfile.getDisks().toArray(new DiskTO[vmProfile.getDisks().size()])); if(vmProfile.getTemplate().getBits() == 32) { to.setArch("i686"); diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 164af74adc0..956d2bc26f7 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -142,8 +142,9 @@ class deployDataCenters(): secondarycmd.url = secondary.url secondarycmd.provider = secondary.providerName secondarycmd.details = [] - for item in secondary.details: - secondarycmd.details.append(item.__dict__) + if secondary.providerName != "NFS": + for item in secondary.details: + secondarycmd.details.append(item.__dict__) if secondarycmd.provider == "NFS": secondarycmd.zoneid = zoneId self.apiClient.addImageStore(secondarycmd) From bf74de23c4fe5aeb2780c4f628089b29401f10f2 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 10 May 2013 10:25:37 -0700 Subject: [PATCH 148/303] CLOUDSTACK-2351: object store - UI - infrastructure menu - secondary storage - Add Secondary Storage - S3 provider - when Create NFS Cache Storage is checked, call extra API createCacheStore. --- ui/scripts/system.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index cfa591dc2db..c81032ff019 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -10633,6 +10633,30 @@ args.response.error(parseXMLHttpResponse(json)); } }); + + if(args.data.createNfsCache == 'on') { + var zoneid = args.data.nfsCacheZoneid; + var nfs_server = args.data.nfsCacheNfsServer; + var path = args.data.nfsCachePath; + var url = nfsURL(nfs_server, path); + + var nfsCacheData = { + provider: 'NFS', + zoneid: zoneid, + url: url + }; + + $.ajax({ + url: createURL('createCacheStore'), + data: nfsCacheData, + success: function(json) { + //do nothing + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } } else if(args.data.provider == 'Swift') { $.ajax({ From 15fc4e137db9cbe8690b3306250d61bdc29093b9 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 10 May 2013 11:22:28 -0700 Subject: [PATCH 149/303] add license header --- .../LocalNfsSecondaryStorageResource.java | 16 ++++++++++++++++ .../subsystem/api/storage/SnapshotResult.java | 16 ++++++++++++++++ .../subsystem/api/storage/SnapshotStrategy.java | 16 ++++++++++++++++ .../cloudstack/storage/to/SnapshotObjectTO.java | 16 ++++++++++++++++ .../MockLocalNfsSecondaryStorageResource.java | 16 ++++++++++++++++ .../cloudstack/storage/test/S3TemplateTest.java | 16 ++++++++++++++++ .../cloudstack/storage/test/TemplateTest.java | 16 ++++++++++++++++ .../storage/snapshot/SnapshotStrategyBase.java | 16 ++++++++++++++++ .../snapshot/XenserverSnapshotStrategy.java | 16 ++++++++++++++++ .../cloudstack/storage/LocalHostEndpoint.java | 16 ++++++++++++++++ .../storage/resource/VmwareStorageProcessor.java | 16 ++++++++++++++++ .../com/cloud/storage/CreateSnapshotPayload.java | 16 ++++++++++++++++ 12 files changed, 192 insertions(+) diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index b7278f7a5d4..4f256863d08 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -1,3 +1,19 @@ +// 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.storage.resource; import static com.cloud.utils.StringUtils.join; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java index 21c0ea04bdf..a886a86b921 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java @@ -1,3 +1,19 @@ +// 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; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java index 6b90c31a465..2a0d2bb30cb 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java @@ -1,3 +1,19 @@ +// 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 com.cloud.storage.Snapshot; diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java index a2e336b53e9..492bd06d67f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -1,3 +1,19 @@ +// 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.to; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index d7a5d3fd1f5..26024ac5aee 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -1,3 +1,19 @@ +// 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; import static com.cloud.utils.StringUtils.join; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java index 07a63c902a3..d88e6dad176 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java @@ -1,3 +1,19 @@ +// 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.test; import java.util.HashMap; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index ad4313a1618..c84fee5bcf9 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -1,3 +1,19 @@ +// 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.test; import static org.testng.Assert.assertTrue; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java index fa0006ae76a..5e78b017fbb 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java @@ -1,3 +1,19 @@ +// 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.snapshot; import javax.inject.Inject; diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 271bee5cf8b..171de4c603c 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -1,3 +1,19 @@ +// 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.snapshot; import java.util.List; diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index d689f36dfe6..9df28040642 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -1,3 +1,19 @@ +// 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; import java.util.concurrent.Executors; diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 988658dbc7c..92c555a16f7 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -1,3 +1,19 @@ +// 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.storage.resource; import java.io.BufferedWriter; diff --git a/server/src/com/cloud/storage/CreateSnapshotPayload.java b/server/src/com/cloud/storage/CreateSnapshotPayload.java index 2eec00d39c3..5adc7462ffe 100644 --- a/server/src/com/cloud/storage/CreateSnapshotPayload.java +++ b/server/src/com/cloud/storage/CreateSnapshotPayload.java @@ -1,3 +1,19 @@ +// 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.storage; import com.cloud.user.Account; From 47f6d650f81166c12b333f18e66d96e919d314b3 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 10 May 2013 12:48:49 -0700 Subject: [PATCH 150/303] fix vmware build --- .../com/cloud/hypervisor/vmware/resource/VmwareResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index f91786fd0af..48b3b3269ea 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -491,7 +491,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((CheckS2SVpnConnectionsCommand) cmd); } else if (clz == ResizeVolumeCommand.class) { return execute((ResizeVolumeCommand) cmd); - } else if (clz == StorageSubSystemCommand.class) { + } else if (cmd instanceof StorageSubSystemCommand) { return this.storageHandler.handleStorageCommands((StorageSubSystemCommand)cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); From dfd6a29fba5466f5b6a109cb247b41c44b6177fa Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Fri, 10 May 2013 17:02:23 -0700 Subject: [PATCH 151/303] Fixed failed unit test --- .../ChildTestConfiguration.java | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java index 6f52397251b..4727cfba99f 100644 --- a/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java +++ b/server/test/org/apache/cloudstack/networkoffering/ChildTestConfiguration.java @@ -19,15 +19,6 @@ package org.apache.cloudstack.networkoffering; import java.io.IOException; -import com.cloud.dc.ClusterDetailsDao; -import com.cloud.dc.dao.*; -import com.cloud.server.ConfigurationServer; -import com.cloud.user.*; -import org.apache.cloudstack.acl.SecurityChecker; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; -import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; -import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; @@ -38,12 +29,29 @@ import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.filter.TypeFilter; +import org.apache.cloudstack.acl.SecurityChecker; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl; +import org.apache.cloudstack.test.utils.SpringUtils; + import com.cloud.agent.AgentManager; import com.cloud.alert.AlertManager; import com.cloud.api.query.dao.UserAccountJoinDaoImpl; import com.cloud.capacity.dao.CapacityDaoImpl; import com.cloud.cluster.agentlb.dao.HostTransferMapDaoImpl; import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.dao.AccountVlanMapDaoImpl; +import com.cloud.dc.dao.ClusterDaoImpl; +import com.cloud.dc.dao.DataCenterDaoImpl; +import com.cloud.dc.dao.DataCenterIpAddressDaoImpl; +import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDao; +import com.cloud.dc.dao.DataCenterVnetDaoImpl; +import com.cloud.dc.dao.DcDetailsDaoImpl; +import com.cloud.dc.dao.HostPodDaoImpl; +import com.cloud.dc.dao.PodVlanDaoImpl; +import com.cloud.dc.dao.PodVlanMapDaoImpl; +import com.cloud.dc.dao.VlanDaoImpl; import com.cloud.domain.dao.DomainDaoImpl; import com.cloud.event.dao.UsageEventDaoImpl; import com.cloud.host.dao.HostDaoImpl; @@ -80,8 +88,8 @@ import com.cloud.network.vpc.dao.PrivateIpDaoImpl; import com.cloud.network.vpn.RemoteAccessVpnService; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; -import com.cloud.offerings.dao.NetworkOfferingServiceMapDaoImpl; import com.cloud.projects.ProjectManager; +import com.cloud.server.ConfigurationServer; import com.cloud.service.dao.ServiceOfferingDaoImpl; import com.cloud.storage.dao.DiskOfferingDaoImpl; import com.cloud.storage.dao.S3DaoImpl; @@ -93,6 +101,11 @@ import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.tags.dao.ResourceTagsDaoImpl; +import com.cloud.user.AccountDetailsDao; +import com.cloud.user.AccountManager; +import com.cloud.user.ResourceLimitService; +import com.cloud.user.UserContext; +import com.cloud.user.UserContextInitializer; import com.cloud.user.dao.AccountDaoImpl; import com.cloud.user.dao.UserDaoImpl; import com.cloud.vm.dao.InstanceGroupDaoImpl; @@ -331,6 +344,10 @@ public class ChildTestConfiguration { return Mockito.mock(AccountDetailsDao.class); } + @Bean + public DataStoreManager dataStoreManager() { + return Mockito.mock(DataStoreManager.class); + } public static class Library implements TypeFilter { From 8a9a7a4adcfaa742134abe49c3d3902c25f1c1b6 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 10 May 2013 17:53:32 -0700 Subject: [PATCH 152/303] Fix a bug in create cache object for S3. --- .../LocalNfsSecondaryStorageResource.java | 79 +++++++++++++++++++ .../resource/NfsSecondaryStorageResource.java | 2 +- .../subsystem/api/storage/HostScope.java | 10 ++- .../subsystem/api/storage/ScopeTest.java | 18 ++--- .../motion/AncientDataMotionStrategy.java | 52 ++++++++---- .../ObjectInDataStoreManagerImpl.java | 2 + .../datastore/PrimaryDataStoreImpl.java | 2 +- .../com/cloud/storage/StorageManagerImpl.java | 2 +- 8 files changed, 138 insertions(+), 29 deletions(-) diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index b7278f7a5d4..66551ef6fa4 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -4,15 +4,18 @@ import static com.cloud.utils.StringUtils.join; import static java.lang.String.format; import static java.util.Arrays.asList; +import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; +import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.amazonaws.services.s3.model.S3ObjectSummary; @@ -23,19 +26,26 @@ import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.template.DownloadManagerImpl; +import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; import com.cloud.utils.S3Utils; import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; @Component public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { + private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class); + public LocalNfsSecondaryStorageResource(){ this._dlMgr = new DownloadManagerImpl(); ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); + _storage = new JavaStorageLayer(); + this._inSystemVM = false; } @Override @@ -100,4 +110,73 @@ public class LocalNfsSecondaryStorageResource extends return new Answer(cmd, false, "Unsupported image data store: " + dstore); } } + + @Override + protected String mount(String root, String nfsPath) { + File file = new File(root); + if (!file.exists()) { + if (_storage.mkdir(root)) { + s_logger.debug("create mount point: " + root); + } else { + s_logger.debug("Unable to create mount point: " + root); + return null; + } + } + + Script script = null; + String result = null; + script = new Script(!_inSystemVM, "mount", _timeout, s_logger); + List res = new ArrayList(); + ZfsPathParser parser = new ZfsPathParser(root); + script.execute(parser); + res.addAll(parser.getPaths()); + for (String s : res) { + if (s.contains(root)) { + return root; + } + } + + Script command = new Script(!_inSystemVM, "mount", _timeout, s_logger); + command.add("-t", "nfs"); + if ("Mac OS X".equalsIgnoreCase(System.getProperty("os.name"))) { + command.add("-o", "resvport"); + } + if (_inSystemVM) { + // Fedora Core 12 errors out with any -o option executed from java + command.add("-o", "soft,timeo=133,retrans=2147483647,tcp,acdirmax=0,acdirmin=0"); + } + command.add(nfsPath); + command.add(root); + result = command.execute(); + if (result != null) { + s_logger.warn("Unable to mount " + nfsPath + " due to " + result); + file = new File(root); + if (file.exists()) + file.delete(); + return null; + } + + // Change permissions for the mountpoint + script = new Script(true, "chmod", _timeout, s_logger); + script.add("777", root); + result = script.execute(); + if (result != null) { + s_logger.warn("Unable to set permissions for " + root + " due to " + result); + return null; + } + + // XXX: Adding the check for creation of snapshots dir here. Might have + // to move it somewhere more logical later. + if (!checkForSnapshotsDir(root)) { + return null; + } + + // Create the volumes dir + if (!checkForVolumesDir(root)) { + return null; + } + + return root; + } + } diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 03e822ebbe7..7fc253c6a44 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -148,7 +148,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String _role; Map _params; protected StorageLayer _storage; - boolean _inSystemVM = false; + protected boolean _inSystemVM = false; boolean _sslCopy = false; protected DownloadManager _dlMgr; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java index 57a448ff2db..ab21f6805e4 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java @@ -24,8 +24,11 @@ import com.cloud.storage.ScopeType; public class HostScope extends AbstractScope { private ScopeType type = ScopeType.HOST; private Long hostId; - public HostScope(Long hostId) { + private Long zoneId; + + public HostScope(Long hostId, Long zoneId) { this.hostId = hostId; + this.zoneId = zoneId; } @Override public ScopeType getScopeType() { @@ -36,4 +39,9 @@ public class HostScope extends AbstractScope { public Long getScopeId() { return this.hostId; } + + public Long getZoneId() { + return zoneId; + } + } diff --git a/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java b/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java index e3ec48c74f0..4b6b361ba07 100644 --- a/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java +++ b/engine/api/test/org/apache/cloudstack/engine/subsystem/api/storage/ScopeTest.java @@ -30,28 +30,28 @@ public class ScopeTest { ZoneScope zoneScope = new ZoneScope(1L); ZoneScope zoneScope2 = new ZoneScope(1L); Assert.assertTrue(zoneScope.isSameScope(zoneScope2)); - + ZoneScope zoneScope3 = new ZoneScope(2L); Assert.assertFalse(zoneScope.isSameScope(zoneScope3)); } - + @Test public void testClusterScope() { ClusterScope clusterScope = new ClusterScope(1L, 1L, 1L); ClusterScope clusterScope2 = new ClusterScope(1L, 1L, 1L); - + Assert.assertTrue(clusterScope.isSameScope(clusterScope2)); - + ClusterScope clusterScope3 = new ClusterScope(2L, 2L, 1L); Assert.assertFalse(clusterScope.isSameScope(clusterScope3)); } - + @Test public void testHostScope() { - HostScope hostScope = new HostScope(1L); - HostScope hostScope2 = new HostScope(1L); - HostScope hostScope3 = new HostScope(2L); - + HostScope hostScope = new HostScope(1L, 1L); + HostScope hostScope2 = new HostScope(1L, 1L); + HostScope hostScope3 = new HostScope(2L, 1L); + Assert.assertTrue(hostScope.isSameScope(hostScope2)); Assert.assertFalse(hostScope.isSameScope(hostScope3)); } 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 index 560c34f0a3f..34ab7bd8c6f 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -23,6 +23,7 @@ import java.util.List; import javax.inject.Inject; +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; 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; @@ -30,6 +31,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; +import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; @@ -137,7 +141,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { // TODO Auto-generated method stub return true; } - + protected boolean needCacheStorage(DataObject srcData, DataObject destData) { DataTO srcTO = srcData.getTO(); DataTO destTO = destData.getTO(); @@ -146,7 +150,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { if (srcStoreTO instanceof NfsTO || srcStoreTO.getRole() == DataStoreRole.ImageCache) { return false; } - + if (destStoreTO instanceof NfsTO || destStoreTO.getRole() == DataStoreRole.ImageCache) { return false; } @@ -161,7 +165,15 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { if (needCacheStorage(srcData, destData)) { //need to copy it to image cache store - DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); + Scope destScope = destData.getDataStore().getScope(); + if (destScope instanceof ClusterScope){ + ClusterScope clusterScope = (ClusterScope)destScope; + destScope = new ZoneScope(clusterScope.getZoneId()); + } else if (destScope instanceof HostScope){ + HostScope hostScope = (HostScope)destScope; + destScope = new ZoneScope(hostScope.getZoneId()); + } + DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); EndPoint ep = selector.select(cacheData, destData); Answer answer = ep.sendMessage(cmd); @@ -180,7 +192,15 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); if (needCacheStorage(srcData, destData)) { //need to copy it to image cache store - DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); + Scope destScope = destData.getDataStore().getScope(); + if (destScope instanceof ClusterScope){ + ClusterScope clusterScope = (ClusterScope)destScope; + destScope = new ZoneScope(clusterScope.getZoneId()); + } else if (destScope instanceof HostScope){ + HostScope hostScope = (HostScope)destScope; + destScope = new ZoneScope(hostScope.getZoneId()); + } + DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); EndPoint ep = selector.select(cacheData, destData); Answer answer = ep.sendMessage(cmd); @@ -193,7 +213,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return answer; } } - + protected DataObject cacheSnapshotChain(SnapshotInfo snapshot) { DataObject leafData = null; while(snapshot != null) { @@ -205,9 +225,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } return leafData; } - + protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) { - + } protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) { @@ -223,15 +243,15 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { if (!(storTO instanceof NfsTO)) { srcData = cacheSnapshotChain(snapshot); } - + String value = configDao .getValue(Config.CreateVolumeFromSnapshotWait.toString()); int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreateVolumeFromSnapshotWait .getDefaultValue())); - + CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait); - + Answer answer = this.storageMgr .sendToPool(pool, cmd); @@ -301,7 +321,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { destData.getType() == DataObjectType.SNAPSHOT) { answer = copySnapshot(srcData, destData); } - + if (answer != null && !answer.getResult()) { errMsg = answer.getDetails(); } @@ -318,7 +338,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { @DB protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destData) { - + String value = configDao .getValue(Config.CreatePrivateTemplateFromSnapshotWait .toString()); @@ -341,13 +361,13 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { private Answer createTemplateFromVolume(DataObject srcData, DataObject destData) { - + String value = configDao .getValue(Config.CreatePrivateTemplateFromVolumeWait.toString()); int _createprivatetemplatefromvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait .getDefaultValue())); - + if (needCacheStorage(srcData, destData)) { //need to copy it to image cache store DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); @@ -372,7 +392,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { try { if (needCacheStorage(srcData, destData)) { cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); - + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); cmd.setCacheTO(cacheData.getTO()); EndPoint ep = selector.select(srcData, destData); @@ -391,7 +411,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } throw new CloudRuntimeException(e.toString()); } - + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index f0b54e1cb3c..5498252cc3a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -134,6 +134,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { TemplateDataStoreVO ts = new TemplateDataStoreVO(); ts.setTemplateId(obj.getId()); ts.setDataStoreId(dataStore.getId()); + ts.setDataStoreRole(dataStore.getRole()); ts.setInstallPath(TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); ts.setState(ObjectInDataStoreStateMachine.State.Allocated); ts = templateDataStoreDao.persist(ts); @@ -143,6 +144,7 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { ss.setSnapshotId(obj.getId()); ss.setDataStoreId(dataStore.getId()); ss.setRole(dataStore.getRole()); + ss.setRole(dataStore.getRole()); ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); ss.setState(ObjectInDataStoreStateMachine.State.Allocated); ss = snapshotDataStoreDao.persist(ss); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 49bfa653114..5f67e471312 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -162,7 +162,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { } else if (vo.getScope() == ScopeType.HOST) { List poolHosts = poolHostDao.listByPoolId(vo.getId()); if (poolHosts.size() > 0) { - return new HostScope(poolHosts.get(0).getHostId()); + return new HostScope(poolHosts.get(0).getHostId(), vo.getDataCenterId()); } s_logger.debug("can't find a local storage in pool host table: " + vo.getId()); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 9f5d2fe80cf..11486ce838a 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -760,7 +760,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStoreRole.Primary); } - HostScope scope = new HostScope(host.getId()); + HostScope scope = new HostScope(host.getId(), pool.getDataCenterId()); lifeCycle.attachHost(store, scope, pInfo); } catch (Exception e) { s_logger.warn("Unable to setup the local storage pool for " + host, e); From 90de46c4fe14fbb86a147138b6025018ff274fd8 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 10 May 2013 17:01:07 -0700 Subject: [PATCH 153/303] get vmware works --- .../cloudstack/storage/to/VolumeObjectTO.java | 1 + engine/storage/integration-test/pom.xml | 6 +++ .../test/DirectAgentManagerSimpleImpl.java | 49 ++++++++++++++++--- .../storage/RemoteHostEndPoint.java | 9 +++- .../endpoint/DefaultEndPointSelector.java | 2 +- .../com/cloud/hypervisor/guru/VMwareGuru.java | 4 +- .../resource/VmwareStorageProcessor.java | 13 ++--- 7 files changed, 66 insertions(+), 18 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 0ae2bc78132..e8bc1766857 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -57,6 +57,7 @@ public class VolumeObjectTO implements DataTO { this.setVolumeId(volume.getId()); this.chainInfo = volume.getChainInfo(); this.volumeType = volume.getVolumeType(); + this.name = volume.getName(); this.setId(volume.getId()); } diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index b5aa7eec6fa..56d36ad3a53 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -61,6 +61,12 @@ cloud-plugin-hypervisor-xen ${project.version} test + + + org.apache.cloudstack + cloud-plugin-hypervisor-vmware + ${project.version} + test org.apache.cloudstack diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index 127c0e30a91..ac5a69d413e 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.storage.test; +import java.net.URI; +import java.net.URISyntaxException; import java.util.HashMap; import java.util.Map; @@ -36,23 +38,33 @@ import com.cloud.agent.api.SetupCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.manager.AgentAttache; import com.cloud.agent.manager.Commands; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.dao.ClusterDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; +import com.cloud.exception.DiscoveryException; import com.cloud.exception.OperationTimedoutException; import com.cloud.host.HostEnvironment; import com.cloud.host.HostVO; import com.cloud.host.Status.Event; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.vmware.VmwareServerDiscoverer; import com.cloud.hypervisor.xen.resource.XcpOssResource; import com.cloud.resource.ServerResource; import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.exception.CloudRuntimeException; public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentManager { private static final Logger logger = Logger.getLogger(DirectAgentManagerSimpleImpl.class); private Map hostResourcesMap = new HashMap(); @Inject HostDao hostDao; + @Inject + ClusterDao clusterDao; + @Inject + ClusterDetailsDao clusterDetailsDao; @Override public boolean configure(String name, Map params) throws ConfigurationException { // TODO Auto-generated method stub @@ -104,14 +116,39 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa ServerResource resource = null; if (host.getHypervisorType() == HypervisorType.XenServer) { resource = new XcpOssResource(); + try { + resource.configure(host.getName(), params); + + } catch (ConfigurationException e) { + logger.debug("Failed to load resource:" + e.toString()); + } + } else if (host.getHypervisorType() == HypervisorType.VMware) { + ClusterVO cluster = clusterDao.findById(host.getClusterId()); + String url = clusterDetailsDao.findDetail(cluster.getId(), "url").getValue(); + URI uri; + try { + uri = new URI(url); + String userName = clusterDetailsDao.findDetail(cluster.getId(), "username").getValue(); + String password = clusterDetailsDao.findDetail(cluster.getId(), "password").getValue(); + VmwareServerDiscoverer discover = new VmwareServerDiscoverer(); + + Map> resources = discover.find(host.getDataCenterId(), host.getPodId(), host.getClusterId(), uri, userName, password, null); + for (Map.Entry> entry : resources.entrySet()) { + resource = entry.getKey(); + } + if (resource == null) { + throw new CloudRuntimeException("can't find resource"); + } + } catch (DiscoveryException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } - try { - resource.configure(host.getName(), params); - hostResourcesMap.put(hostId, resource); - } catch (ConfigurationException e) { - logger.debug("Failed to load resource:" + e.toString()); - } + hostResourcesMap.put(hostId, resource); HostEnvironment env = new HostEnvironment(); SetupCommand cmd = new SetupCommand(env); cmd.setNeedSetup(true); diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 8e96bffae9d..7a651c009e0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -41,6 +41,7 @@ import com.cloud.exception.ConnectionException; import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.host.Status; +import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.utils.component.ComponentContext; import com.cloud.utils.exception.CloudRuntimeException; @@ -52,6 +53,8 @@ public class RemoteHostEndPoint implements EndPoint { AgentManager agentMgr; @Inject HostEndpointRpcServer rpcServer; + @Inject + protected HypervisorGuruManager _hvGuruMgr; private ScheduledExecutorService executor; public RemoteHostEndPoint() { @@ -83,7 +86,8 @@ public class RemoteHostEndPoint implements EndPoint { public Answer sendMessage(Command cmd) { String errMsg = null; try { - return agentMgr.send(getId(), cmd); + long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd); + return agentMgr.send(newHostId, cmd); } catch (AgentUnavailableException e) { errMsg = e.toString(); s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); @@ -160,7 +164,8 @@ public class RemoteHostEndPoint implements EndPoint { @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { try { - agentMgr.send(this.hostId, new Commands(cmd), new CmdRunner(callback)); + long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(this.hostId, cmd); + agentMgr.send(newHostId, new Commands(cmd), new CmdRunner(callback)); } catch (AgentUnavailableException e) { throw new CloudRuntimeException("Unable to send message", e); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 54059f28a59..de57dd7f2fe 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -58,7 +58,7 @@ public class DefaultEndPointSelector implements EndPointSelector { @Inject HostDao hostDao; private String findOneHostInaScope = "select id from host where " - + " status = 'Up' and hypervisor_type != 'VMware' and type in ('Routing', 'SecondaryStorageVM') "; + + " status = 'Up' and type in ('Routing', 'SecondaryStorageVM') "; private String findOneHostOnPrimaryStorage = "select id from host where " + "status = 'Up' and type = 'Routing' "; diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index 55bb1e98366..3388fc7b1a4 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -28,6 +28,7 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.cloudstack.api.ApiConstants.VMDetails; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -286,7 +287,8 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru { cmd instanceof CopyVolumeCommand || cmd instanceof CreateVolumeOVACommand || cmd instanceof PrepareOVAPackingCommand || - cmd instanceof CreateVolumeFromSnapshotCommand) { + cmd instanceof CreateVolumeFromSnapshotCommand || + cmd instanceof CopyCommand) { needDelegation = true; } /* Fang: remove this before checking in */ diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 92c555a16f7..240c62f5a4a 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -328,14 +328,11 @@ public class VmwareStorageProcessor implements StorageProcessor { public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); TemplateObjectTO template = (TemplateObjectTO)srcData; - DataStoreTO imageStore = template.getDataStore(); DataTO destData = cmd.getDestTO(); VolumeObjectTO volume = (VolumeObjectTO)destData; PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); - if (imageStore != null && !(imageStore instanceof NfsTO)) { - return new CopyCmdAnswer("unsupported protocol"); - } - NfsTO nfsImageStore = (NfsTO)imageStore; + PrimaryDataStoreTO srcStore = (PrimaryDataStoreTO)template.getDataStore(); + try { VmwareContext context = this.hostService.getServiceContext(null); @@ -351,7 +348,7 @@ public class VmwareStorageProcessor implements StorageProcessor { // attach volume id to make the name unique String vmdkName = volume.getName() + "-" + volume.getId(); - if (nfsImageStore == null) { + if (srcStore == null) { // create a root volume for blank VM String dummyVmName = this.hostService.getWorkerName(context, cmd, 0); @@ -379,8 +376,8 @@ public class VmwareStorageProcessor implements StorageProcessor { vmMo.destroy(); } } else { - String templateUrl = nfsImageStore.getUrl() + File.separator + template.getPath(); - VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUrl), true); + String templatePath = template.getPath(); + VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templatePath), true); if (vmTemplate == null) { s_logger.warn("Template host in vSphere is not in connected state, request template reload"); return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload"); From 36146e7f65e6a7d55027c522ef899a179dc1507f Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 10 May 2013 19:22:09 -0700 Subject: [PATCH 154/303] create volume command needs to send to vmwareresource --- .../com/cloud/hypervisor/guru/VMwareGuru.java | 22 ++++++++++++++++++- .../src/com/cloud/server/StatsCollector.java | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index 3388fc7b1a4..95521e8f83d 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -42,6 +42,9 @@ import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateVolumeOVACommand; import com.cloud.agent.api.storage.PrepareOVAPackingCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.cluster.ClusterManager; @@ -64,6 +67,7 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.secstorage.CommandExecLogDao; import com.cloud.secstorage.CommandExecLogVO; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.GuestOSVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; @@ -289,7 +293,23 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru { cmd instanceof PrepareOVAPackingCommand || cmd instanceof CreateVolumeFromSnapshotCommand || cmd instanceof CopyCommand) { - needDelegation = true; + if (cmd instanceof CopyCommand) { + CopyCommand cpyCommand = (CopyCommand)cmd; + DataTO srcData = cpyCommand.getSrcTO(); + DataStoreTO srcStoreTO = srcData.getDataStore(); + DataTO destData = cpyCommand.getDestTO(); + DataStoreTO destStoreTO = destData.getDataStore(); + + if (destData.getObjectType() == DataObjectType.VOLUME && destStoreTO.getRole() == DataStoreRole.Primary && + srcData.getObjectType() == DataObjectType.TEMPLATE && srcStoreTO.getRole() == DataStoreRole.Primary) { + needDelegation = false; + } else { + needDelegation = true; + } + } else { + needDelegation = true; + } + } /* Fang: remove this before checking in */ // needDelegation = false; diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index 1398672d4d5..3feb10b3da8 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -321,7 +321,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc GetStorageStatsCommand command = new GetStorageStatsCommand(pool.getUuid(), pool.getPoolType(), pool.getPath()); long poolId = pool.getId(); try { - Answer answer = _storageManager.sendToPool(pool.getId(), command); + Answer answer = _storageManager.sendToPool(pool, command); if (answer != null && answer.getResult()) { storagePoolStats.put(pool.getId(), (StorageStats)answer); From 993187622e15514b61a06019e8885172d605dc7f Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 10 May 2013 20:39:02 -0700 Subject: [PATCH 155/303] fix compile, after rebase to master --- .../agent/api/MigrateWithStorageAnswer.java | 10 +- .../api/MigrateWithStorageCompleteAnswer.java | 9 +- .../storage/test/VolumeTestVmware.java | 445 ++++++++++++++++++ .../xen/resource/XenServer610Resource.java | 23 +- .../XenServerStorageMotionStrategy.java | 5 +- .../driver/SwiftImageStoreDriverImpl.java | 6 +- .../SamplePrimaryDatastoreProviderImpl.java | 2 +- tools/apidoc/gen_toc.py | 4 + 8 files changed, 483 insertions(+), 21 deletions(-) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java index 06aff323bdc..d87a5f184c8 100644 --- a/core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java +++ b/core/src/com/cloud/agent/api/MigrateWithStorageAnswer.java @@ -17,23 +17,27 @@ package com.cloud.agent.api; import java.util.List; + +import org.apache.cloudstack.storage.to.VolumeObjectTO; + +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.VolumeTO; public class MigrateWithStorageAnswer extends Answer { - List volumeTos; + List volumeTos; public MigrateWithStorageAnswer(MigrateWithStorageCommand cmd, Exception ex) { super(cmd, ex); volumeTos = null; } - public MigrateWithStorageAnswer(MigrateWithStorageCommand cmd, List volumeTos) { + public MigrateWithStorageAnswer(MigrateWithStorageCommand cmd, List volumeTos) { super(cmd, true, null); this.volumeTos = volumeTos; } - public List getVolumeTos() { + public List getVolumeTos() { return volumeTos; } } diff --git a/core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java b/core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java index 920cf48ca49..fd8f22f3579 100644 --- a/core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java +++ b/core/src/com/cloud/agent/api/MigrateWithStorageCompleteAnswer.java @@ -17,22 +17,25 @@ package com.cloud.agent.api; import java.util.List; + +import org.apache.cloudstack.storage.to.VolumeObjectTO; + import com.cloud.agent.api.to.VolumeTO; public class MigrateWithStorageCompleteAnswer extends Answer { - List volumeTos; + List volumeTos; public MigrateWithStorageCompleteAnswer(MigrateWithStorageCompleteCommand cmd, Exception ex) { super(cmd, ex); volumeTos = null; } - public MigrateWithStorageCompleteAnswer(MigrateWithStorageCompleteCommand cmd, List volumeTos) { + public MigrateWithStorageCompleteAnswer(MigrateWithStorageCompleteCommand cmd, List volumeTos) { super(cmd, true, null); this.volumeTos = volumeTos; } - public List getVolumeTos() { + public List getVolumeTos() { return volumeTos; } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java new file mode 100644 index 00000000000..48f1a2ac627 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java @@ -0,0 +1,445 @@ +/* + * 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.test; + +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.RemoteHostEndPoint; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +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.apache.cloudstack.storage.volume.db.VolumeDao2; +import org.apache.cloudstack.storage.volume.db.VolumeVO; +import org.mockito.Mockito; +import org.springframework.test.context.ContextConfiguration; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +import com.cloud.agent.AgentManager; +import com.cloud.dc.ClusterDetailsDao; +import com.cloud.dc.ClusterDetailsVO; +import com.cloud.dc.ClusterVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.host.Host; +import com.cloud.host.Host.Type; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.org.Cluster.ClusterType; +import com.cloud.org.Managed.ManagedState; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ResourceState; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; +import com.cloud.storage.Storage; +import com.cloud.storage.StoragePoolStatus; +import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.Storage.TemplateType; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.utils.component.ComponentContext; + +@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +public class VolumeTestVmware extends CloudStackTestNGBase { + @Inject + ImageStoreDao imageStoreDao; + ImageStoreVO imageStore; + Long dcId; + Long clusterId; + Long podId; + HostVO host; + String primaryName = "my primary data store"; + DataStore primaryStore; + @Inject + HostDao hostDao; + @Inject + TemplateService imageService; + @Inject + VolumeService volumeService; + @Inject + VMTemplateDao imageDataDao; + @Inject + VolumeDao2 volumeDao; + @Inject + HostPodDao podDao; + @Inject + ClusterDao clusterDao; + @Inject + ClusterDetailsDao clusterDetailsDao; + @Inject + DataCenterDao dcDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + @Inject + DataStoreProviderManager dataStoreProviderMgr; + @Inject + TemplateDataStoreDao templateStoreDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + PrimaryDataStoreDao primaryDataStoreDao; + @Inject + AgentManager agentMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + ResourceManager resourceMgr; + @Inject + VolumeDataFactory volFactory; + @Inject + EndPointSelector epSelector; + long primaryStoreId; + VMTemplateVO image; + String imageStoreName = "testImageStore"; + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + + host = hostDao.findByGuid(this.getHostGuid()); + if (host != null) { + dcId = host.getDataCenterId(); + clusterId = host.getClusterId(); + podId = host.getPodId(); + imageStore = this.imageStoreDao.findByName(imageStoreName); + } else { + //create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", + null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + //create pod + + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); + pod = podDao.persist(pod); + podId = pod.getId(); + //create xen cluster + ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); + cluster.setHypervisorType(HypervisorType.VMware.toString()); + cluster.setClusterType(ClusterType.ExternalManaged); + cluster.setManagedState(ManagedState.Managed); + cluster = clusterDao.persist(cluster); + clusterId = cluster.getId(); + + //setup vcenter + ClusterDetailsVO clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "url", null); + this.clusterDetailsDao.persist(clusterDetailVO); + clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "username", null); + this.clusterDetailsDao.persist(clusterDetailVO); + clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "password", null); + this.clusterDetailsDao.persist(clusterDetailVO); + //create xen host + + host = new HostVO(this.getHostGuid()); + host.setName("devcloud vmware host"); + host.setType(Host.Type.Routing); + host.setPrivateIpAddress(this.getHostIp()); + host.setDataCenterId(dc.getId()); + host.setVersion("6.0.1"); + host.setAvailable(true); + host.setSetup(true); + host.setPodId(podId); + host.setLastPinged(0); + host.setResourceState(ResourceState.Enabled); + host.setHypervisorType(HypervisorType.VMware); + host.setClusterId(cluster.getId()); + + host = hostDao.persist(host); + + imageStore = new ImageStoreVO(); + imageStore.setName(imageStoreName); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore.setProtocol("nfs"); + imageStore = imageStoreDao.persist(imageStore); + } + + image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + + image = imageDataDao.persist(image); + + /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); + + templateStore.setDataStoreId(imageStore.getId()); + templateStore.setDownloadPercent(100); + templateStore.setDownloadState(Status.DOWNLOADED); + templateStore.setDownloadUrl(imageStore.getUrl()); + templateStore.setInstallPath(this.getImageInstallPath()); + templateStore.setTemplateId(image.getId()); + templateStoreDao.persist(templateStore);*/ + + + DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); + TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image); + DataObject templateOnStore = store.create(template); + TemplateObjectTO to = new TemplateObjectTO(); + to.setPath(this.getImageInstallPath()); + CopyCmdAnswer answer = new CopyCmdAnswer(to); + templateOnStore.processEvent(Event.CreateOnlyRequested); + templateOnStore.processEvent(Event.OperationSuccessed, answer); + + + } + + @Override + protected void injectMockito() { + List hosts = new ArrayList(); + hosts.add(this.host); + Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); + + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + } + + public DataStore createPrimaryDataStore() { + try { + String uuid = UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString(); + List pools = primaryDataStoreDao.findPoolByName(this.primaryName); + if (pools.size() > 0) { + return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); + } + + /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); + Map params = new HashMap(); + URI uri = new URI(this.getPrimaryStorageUrl()); + params.put("url", this.getPrimaryStorageUrl()); + params.put("server", uri.getHost()); + params.put("path", uri.getPath()); + params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); + params.put("zoneId", dcId); + params.put("clusterId", clusterId); + params.put("name", this.primaryName); + params.put("port", 1); + params.put("podId", this.podId); + params.put("roles", DataStoreRole.Primary.toString()); + params.put("uuid", uuid); + params.put("providerName", String.valueOf(provider.getName())); + + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + DataStore store = lifeCycle.initialize(params); + ClusterScope scope = new ClusterScope(clusterId, podId, dcId); + lifeCycle.attachCluster(store, scope);*/ + + StoragePoolVO pool = new StoragePoolVO(); + pool.setClusterId(clusterId); + pool.setDataCenterId(dcId); + URI uri = new URI(this.getPrimaryStorageUrl()); + pool.setHostAddress(uri.getHost()); + pool.setPath(uri.getPath()); + pool.setPort(0); + pool.setName(this.primaryName); + pool.setUuid(this.getPrimaryStorageUuid()); + pool.setStatus(StoragePoolStatus.Up); + pool.setPoolType(StoragePoolType.VMFS); + pool.setPodId(podId); + pool.setScope(ScopeType.CLUSTER); + pool.setStorageProviderName("cloudstack primary data store provider"); + pool = this.primaryStoreDao.persist(pool); + DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + return store; + } catch (Exception e) { + return null; + } + } + + private VolumeVO createVolume(Long templateId, long dataStoreId) { + VolumeVO volume = new VolumeVO(1000, new RootDisk().toString(), UUID.randomUUID().toString(), templateId); + volume.setPoolId(dataStoreId); + volume = volumeDao.persist(volume); + return volume; + } + + //@Test + public void testCopyBaseImage() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); + try { + VolumeApiResult result = future.get(); + + AssertJUnit.assertTrue(result.isSuccess()); + + VolumeInfo newVol = result.getVolume(); + this.volumeService.destroyVolume(newVol.getId()); + VolumeInfo vol = this.volFactory.getVolume(volume.getId()); + this.volumeService.expungeVolumeAsync(vol); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + @Test + public void testCreateDataDisk() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + this.volumeService.createVolumeAsync(volInfo, primaryStore); + } + + @Test + public void testDeleteDisk() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); + try { + VolumeApiResult result = future.get(); + VolumeInfo vol = result.getVolume(); + + this.volumeService.destroyVolume(volInfo.getId()); + volInfo = this.volFactory.getVolume(vol.getId()); + this.volumeService.expungeVolumeAsync(volInfo); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ConcurrentOperationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + private VMTemplateVO createTemplateInDb() { + image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + image = imageDataDao.persist(image); + return image; + } + + @Test + public void testCreateTemplateFromVolume() { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); + try { + VolumeApiResult result = future.get(); + + AssertJUnit.assertTrue(result.isSuccess()); + volInfo = result.getVolume(); + VMTemplateVO templateVO = createTemplateInDb(); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); + DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); + + this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } +} diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java index bb31136f38e..95896611fc1 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer610Resource.java @@ -26,6 +26,7 @@ import java.util.Set; import javax.ejb.Local; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import com.cloud.resource.ServerResource; @@ -46,6 +47,7 @@ import com.cloud.agent.api.MigrateWithStorageCompleteAnswer; import com.cloud.agent.api.MigrateWithStorageCompleteCommand; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.network.Networks.TrafficType; +import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.agent.api.to.NicTO; @@ -103,9 +105,9 @@ public class XenServer610Resource extends XenServer56FP1Resource { } } - private List getUpdatedVolumePathsOfMigratedVm(Connection connection, VM migratedVm, - VolumeTO[] volumes) throws CloudRuntimeException { - List volumeToList = new ArrayList(); + private List getUpdatedVolumePathsOfMigratedVm(Connection connection, VM migratedVm, + DiskTO[] volumes) throws CloudRuntimeException { + List volumeToList = new ArrayList(); try { // Volume paths would have changed. Return that information. @@ -120,11 +122,14 @@ public class XenServer610Resource extends XenServer56FP1Resource { } } - for (VolumeTO volumeTo : volumes) { - Long deviceId = volumeTo.getDeviceId(); + for (DiskTO volumeTo : volumes) { + VolumeObjectTO vol = (VolumeObjectTO)volumeTo.getData(); + Long deviceId = volumeTo.getDiskSeq(); VDI vdi = deviceIdToVdiMap.get(deviceId.toString()); - volumeTo.setPath(vdi.getUuid(connection)); - volumeToList.add(volumeTo); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(vdi.getUuid(connection)); + newVol.setId(vol.getId()); + volumeToList.add(newVol); } } catch (Exception e) { s_logger.error("Unable to get the updated VDI paths of the migrated vm " + e.toString(), e); @@ -194,7 +199,7 @@ public class XenServer610Resource extends XenServer56FP1Resource { } // Volume paths would have changed. Return that information. - List volumeToList = getUpdatedVolumePathsOfMigratedVm(connection, vmToMigrate, vmSpec.getDisks()); + List volumeToList = getUpdatedVolumePathsOfMigratedVm(connection, vmToMigrate, vmSpec.getDisks()); vmToMigrate.setAffinity(connection, host); state = State.Stopping; @@ -370,7 +375,7 @@ public class XenServer610Resource extends XenServer56FP1Resource { } // Volume paths would have changed. Return that information. - List volumeToSet = getUpdatedVolumePathsOfMigratedVm(connection, migratedVm, vmSpec.getDisks()); + List volumeToSet = getUpdatedVolumePathsOfMigratedVm(connection, migratedVm, vmSpec.getDisks()); migratedVm.setAffinity(connection, host); synchronized (_cluster.intern()) { diff --git a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java index e92b81861db..49c61fa3b83 100644 --- a/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java +++ b/plugins/hypervisors/xen/src/org/apache/cloudstack/storage/motion/XenServerStorageMotionStrategy.java @@ -35,6 +35,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; 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.to.VolumeObjectTO; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -213,12 +214,12 @@ public class XenServerStorageMotionStrategy implements DataMotionStrategy { } } - private void updateVolumePathsAfterMigration(Map volumeToPool, List volumeTos) { + private void updateVolumePathsAfterMigration(Map volumeToPool, List volumeTos) { for (Map.Entry entry : volumeToPool.entrySet()) { boolean updated = false; VolumeInfo volume = entry.getKey(); StoragePool pool = (StoragePool)entry.getValue(); - for (VolumeTO volumeTo : volumeTos) { + for (VolumeObjectTO volumeTo : volumeTos) { if (volume.getId() == volumeTo.getId()) { VolumeVO volumeVO = volDao.findById(volume.getId()); Long oldPoolId = volumeVO.getPoolId(); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 82df043bb81..db3b225c1ef 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -203,7 +203,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { CreateCmdResult result = new CreateCmdResult(null, null); - result.setSucess(false); + //result.setSucess(false); result.setResult(answer.getErrorString()); caller.complete(result); } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { @@ -295,14 +295,14 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { if (answer == null || !answer.getResult()) { s_logger.debug("Failed to deleted template at store: " + store.getName()); CommandResult result = new CommandResult(); - result.setSucess(false); + //result.setSucess(false); result.setResult("Delete template failed"); callback.complete(result); } else { s_logger.debug("Deleted template at: " + installPath); CommandResult result = new CommandResult(); - result.setSucess(true); + //result.setSucess(true); callback.complete(result); } diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java index 93eae0a660a..57424a7e0c3 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java @@ -57,7 +57,7 @@ public class SamplePrimaryDatastoreProviderImpl implements PrimaryDataStoreProvi @Override public boolean configure(Map params) { - lifecyle = ComponentContext.inject(SamplePrimaryDataStoreLifeCycleImpl.class); + lifecycle = ComponentContext.inject(SamplePrimaryDataStoreLifeCycleImpl.class); driver = ComponentContext.inject(SamplePrimaryDataStoreDriverImpl.class); listener = ComponentContext.inject(DefaultHostListener.class); return true; diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index f8bdae281b2..f60c18ee7aa 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -140,6 +140,10 @@ known_categories = { 'removeIpFromNic': 'Nic', 'listNics':'Nic', 'AffinityGroup': 'Affinity Group', + 'addImageStore': 'Image Store', + 'listImageStore': 'Image Store', + 'deleteImageStore': 'Image Store', + 'createCacheStore': 'Image Store', } From 3d91a4e01201fce2126dae51bb52369a85b5e102 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sat, 11 May 2013 18:18:12 -0700 Subject: [PATCH 156/303] Fix a bug in searching for existing image stores. --- server/src/com/cloud/storage/StorageManagerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 11486ce838a..de63008c528 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1879,7 +1879,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // check if we have already image stores from other different providers, we currently are not supporting image stores from different // providers co-existing - List imageStores = _imageStoreDao.listAll(); + List imageStores = _imageStoreDao.listImageStores(); for ( ImageStoreVO store : imageStores){ if (!store.getProviderName().equalsIgnoreCase(providerName)){ throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + " already added"); From f8e51f70a14d1d7d263b07c8a99ca666fbc8a9a5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sat, 11 May 2013 18:19:29 -0700 Subject: [PATCH 157/303] Invoke reatetmplt.sh script after copying template from S3 to cache storage. --- .../LocalNfsSecondaryStorageResource.java | 1 + .../resource/NfsSecondaryStorageResource.java | 55 ++++++++++++++++++- .../manager/StorageCacheManagerImpl.java | 10 +--- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java index 66551ef6fa4..97320ca589a 100644 --- a/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/LocalNfsSecondaryStorageResource.java @@ -46,6 +46,7 @@ public class LocalNfsSecondaryStorageResource extends ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); _storage = new JavaStorageLayer(); this._inSystemVM = false; + System.setProperty("paths.script", "/Users/minc/dev/cloud-asf"); //This is just for my testing, not for QA build } @Override diff --git a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java index 7fc253c6a44..b160315314b 100755 --- a/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java +++ b/core/src/com/cloud/storage/resource/NfsSecondaryStorageResource.java @@ -55,6 +55,7 @@ import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -237,7 +238,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S try { - final File downloadDirectory = _storage.getFile(determineStorageTemplatePath(storagePath, destPath)); + String downloadPath = determineStorageTemplatePath(storagePath, destPath); + final File downloadDirectory = _storage.getFile(downloadPath); downloadDirectory.mkdirs(); if (!downloadDirectory.exists()) { @@ -267,12 +269,59 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new CopyCmdAnswer("Can't find template"); } + // do post processing to unzip the file if it is compressed + String scriptsDir = "scripts/storage/secondary"; + String createTmpltScr = Script.findScript(scriptsDir, "createtmplt.sh"); + if (createTmpltScr == null) { + throw new ConfigurationException("Unable to find createtmplt.sh"); + } + s_logger.info("createtmplt.sh found in " + createTmpltScr); + String createVolScr = Script.findScript(scriptsDir, "createvolume.sh"); + if (createVolScr == null) { + throw new ConfigurationException("Unable to find createvolume.sh"); + } + s_logger.info("createvolume.sh found in " + createVolScr); + String script = srcData.getObjectType() == DataObjectType.TEMPLATE ? createTmpltScr : createVolScr; + + int installTimeoutPerGig = 180 * 60 * 1000; + int imgSizeGigs = (int) Math.ceil(destFile.length() * 1.0d / (1024 * 1024 * 1024)); + imgSizeGigs++; // add one just in case + long timeout = imgSizeGigs * installTimeoutPerGig; + + String origPath = destFile.getAbsolutePath(); + String extension = null; + if ( srcData.getObjectType() == DataObjectType.TEMPLATE){ + extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension(); + } else{ + extension = ((VolumeObjectTO)srcData).getDiskType().toString().toLowerCase(); + } + + String templateName = UUID.randomUUID().toString(); + String templateFilename = templateName + "." + extension; + Script scr = new Script(script, timeout, s_logger); + scr.add("-s", Integer.toString(imgSizeGigs)); // not used for now + scr.add("-n", templateFilename); + + scr.add("-t", downloadPath); + scr.add("-f", origPath); // this is the temporary + // template file downloaded + String result; + result = scr.execute(); + + if (result != null) { + // script execution failure + throw new CloudRuntimeException("Failed to run script " + script); + } + + String finalFileName = templateFilename; + String finalDownloadPath = destPath + File.separator + templateFilename; + DataTO newDestTO = null; if (destData.getObjectType() == DataObjectType.TEMPLATE) { TemplateObjectTO newTemplTO = new TemplateObjectTO(); - newTemplTO.setPath(destPath + File.separator + destFile.getName()); - newTemplTO.setName(destFile.getName()); + newTemplTO.setPath(finalDownloadPath); + newTemplTO.setName(finalFileName); newDestTO = newTemplTO; } else { return new CopyCmdAnswer("not implemented yet"); 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 index be1983e10eb..8fb898e12e1 100644 --- 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 @@ -39,6 +39,7 @@ import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CopyCmdAnswer; +import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.log4j.Logger; import com.cloud.utils.component.Manager; @@ -50,6 +51,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { List storageCacheAllocator; @Inject DataMotionService dataMotionSvr; + @Override public DataStore getCacheStorage(Scope scope) { for (StorageCacheAllocator allocator : storageCacheAllocator) { @@ -131,16 +133,10 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { @Override public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); + //TODO: consider multiple thread to create DataObject objOnCacheStore = cacheStore.create(data); AsyncCallFuture future = new AsyncCallFuture(); - /* - CreateCacheObjectContext context = new CreateCacheObjectContext(null, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setContext(context); - caller.setCallback(future); - */ - CopyCommandResult result = null; try { objOnCacheStore.processEvent(Event.CreateOnlyRequested); From 0d580ccb26e55f0d17e04a98f470116bef6073b2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sat, 11 May 2013 22:00:40 -0700 Subject: [PATCH 158/303] Fix NPE in adding host and also put back lost change in deployDataCenter due to rebase with master. --- .../storage/image/TemplateServiceImpl.java | 8 ++++-- .../com/cloud/storage/StorageManagerImpl.java | 2 +- tools/devcloud/devcloud_s3.cfg | 2 +- tools/marvin/marvin/deployDataCenter.py | 25 ++++++++++++++++--- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 057247598ce..bf8155bec4c 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -463,7 +463,9 @@ public class TemplateServiceImpl implements TemplateService { if (callbackResult.isFailed()) { template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); result.setResult(callbackResult.getResult()); - parentCallback.complete(result); + if ( parentCallback != null ){ + parentCallback.complete(result); + } return null; } @@ -471,7 +473,9 @@ public class TemplateServiceImpl implements TemplateService { template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); } catch (Exception e) { result.setResult(e.toString()); - parentCallback.complete(result); + if ( parentCallback != null ){ + parentCallback.complete(result); + } return null; } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 4ff590ea751..f03e9f99e04 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -736,7 +736,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStoreRole.Primary); } - HostScope scope = new HostScope(host.getId(), pool.getDataCenterId()); + HostScope scope = new HostScope(host.getId(), host.getDataCenterId()); lifeCycle.attachHost(store, scope, pInfo); } catch (Exception e) { s_logger.warn("Unable to setup the local storage pool for " + host, e); diff --git a/tools/devcloud/devcloud_s3.cfg b/tools/devcloud/devcloud_s3.cfg index ea5056469f6..18efec35d37 100644 --- a/tools/devcloud/devcloud_s3.cfg +++ b/tools/devcloud/devcloud_s3.cfg @@ -106,7 +106,7 @@ ], "cacheStorages": [ { - "url": "nfs://192.168.56.10/opt/storage/cache", + "url": "nfs://192.168.56.10/opt/storage/secondary", "providerName": "NFS", "details": [ ] diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index 21685923b37..dd6db051e8d 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -138,10 +138,28 @@ class deployDataCenters(): if secondaryStorages is None: return for secondary in secondaryStorages: - secondarycmd = addSecondaryStorage.addSecondaryStorageCmd() + secondarycmd = addImageStore.addImageStoreCmd() secondarycmd.url = secondary.url - secondarycmd.zoneid = zoneId - self.apiClient.addSecondaryStorage(secondarycmd) + secondarycmd.provider = secondary.providerName + secondarycmd.details = [] + for item in secondary.details: + secondarycmd.details.append(item.__dict__) + if secondarycmd.provider == "NFS": + secondarycmd.zoneid = zoneId + self.apiClient.addImageStore(secondarycmd) + + def createCacheStorages(self, cacheStorages, zoneId): + if cacheStorages is None: + return + for cache in cacheStorages: + cachecmd = createCacheStore.createCacheStoreCmd() + cachecmd.url = cache.url + cachecmd.provider = cache.providerName + cachecmd.zoneid = zoneId + cachecmd.details = [] + for item in cache.details: + cachecmd.details.append(item.__dict__) + self.apiClient.createCacheStore(cachecmd) def createnetworks(self, networks, zoneId): if networks is None: @@ -328,6 +346,7 @@ class deployDataCenters(): zoneId) self.createSecondaryStorages(zone.secondaryStorages, zoneId) + self.createCacheStorages(zone.cacheStorages, zoneId) enabled = getattr(zone, 'enabled', 'True') if enabled == 'True' or enabled is None: From fdb523d2195273eaf3e7e04fe04435b4a1d73833 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sun, 12 May 2013 00:01:44 -0700 Subject: [PATCH 159/303] Remove a debug code. --- .../resource/LocalNfsSecondaryStorageResource.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java index bce01ae291a..53c96ddf518 100644 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java @@ -28,6 +28,7 @@ import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; + import org.apache.cloudstack.storage.template.DownloadManagerImpl; import org.apache.cloudstack.storage.template.DownloadManagerImpl.ZfsPathParser; import com.cloud.utils.S3Utils; @@ -45,16 +46,6 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc ((DownloadManagerImpl) _dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); _storage = new JavaStorageLayer(); this._inSystemVM = false; - System.setProperty("paths.script", "/Users/minc/dev/cloud-asf"); // This - // is - // just - // for - // my - // testing, - // not - // for - // QA - // build } @Override From e8259e38c2ede27c9047dfd13c8a1d4a6f0c303e Mon Sep 17 00:00:00 2001 From: Edison Su Date: Sun, 12 May 2013 14:41:06 -0700 Subject: [PATCH 160/303] integration test is passed again --- engine/pom.xml | 14 +++++++++++++- .../storage/test/ChildTestConfiguration.java | 6 ++++++ .../cloudstack/storage/test/SnapshotTest.java | 8 ++++++++ .../apache/cloudstack/storage/test/VolumeTest.java | 11 +++++++++-- .../test/resource/storageContext.xml | 2 +- engine/storage/pom.xml | 5 +++++ .../cloudstack/storage/LocalHostEndpoint.java | 3 ++- .../xen/resource/XenServerStorageProcessor.java | 1 + setup/db/db/schema-410to420.sql | 1 - 9 files changed, 45 insertions(+), 6 deletions(-) diff --git a/engine/pom.xml b/engine/pom.xml index 43486cbf10e..3d305bc5c40 100644 --- a/engine/pom.xml +++ b/engine/pom.xml @@ -40,10 +40,22 @@ storage/datamotion storage/cache storage/snapshot - storage/integration-test components-api schema network service + + + integration-test + + + nonoss + + + + storage/integration-test + + + diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index 24e685ab885..acb61069074 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -59,6 +59,7 @@ import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDaoImpl; import com.cloud.host.dao.HostDetailsDaoImpl; import com.cloud.host.dao.HostTagsDaoImpl; +import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; import com.cloud.server.auth.UserAuthenticator; @@ -251,6 +252,11 @@ public class ChildTestConfiguration extends TestConfiguration { public AlertManager alertMgr() { return Mockito.mock(AlertManager.class); } + + @Bean + public HypervisorGuruManager hypervisorGuruMgr() { + return Mockito.mock(HypervisorGuruManager.class); + } public static class Library implements TypeFilter { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index acd32b49701..e772c821d83 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -64,6 +64,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; @@ -75,6 +76,7 @@ import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.Host.Type; import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; @@ -87,6 +89,7 @@ import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.dao.SnapshotDao; @@ -133,6 +136,8 @@ public class SnapshotTest extends CloudStackTestNGBase { @Inject AgentManager agentMgr; @Inject + HypervisorGuruManager hyGuruMgr; + @Inject DataStoreManager dataStoreMgr; @Inject ResourceManager resourceMgr; @@ -244,6 +249,7 @@ public class SnapshotTest extends CloudStackTestNGBase { DataObject templateOnStore = store.create(template); TemplateObjectTO to = new TemplateObjectTO(); to.setPath(this.getImageInstallPath()); + to.setFormat(ImageFormat.VHD); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); @@ -261,6 +267,8 @@ public class SnapshotTest extends CloudStackTestNGBase { Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId()); + } public DataStore createPrimaryDataStore() { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index fe628794b94..c610e505367 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -65,6 +65,7 @@ import org.testng.AssertJUnit; import org.testng.annotations.Test; import com.cloud.agent.AgentManager; +import com.cloud.agent.api.Command; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; @@ -78,6 +79,7 @@ import com.cloud.host.Host.Type; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.HypervisorGuruManager; import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceManager; @@ -85,6 +87,7 @@ import com.cloud.resource.ResourceState; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.Storage; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; @@ -140,6 +143,8 @@ public class VolumeTest extends CloudStackTestNGBase { VolumeDataFactory volFactory; @Inject EndPointSelector epSelector; + @Inject + HypervisorGuruManager hyGuruMgr; long primaryStoreId; VMTemplateVO image; String imageStoreName = "testImageStore"; @@ -192,7 +197,7 @@ public class VolumeTest extends CloudStackTestNGBase { imageStore = new ImageStoreVO(); imageStore.setName(imageStoreName); imageStore.setDataCenterId(dcId); - imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setProviderName(DataStoreProvider.NFS_IMAGE); imageStore.setRole(DataStoreRole.Image); imageStore.setUrl(this.getSecondaryStorage()); imageStore.setUuid(UUID.randomUUID().toString()); @@ -236,6 +241,7 @@ public class VolumeTest extends CloudStackTestNGBase { DataObject templateOnStore = store.create(template); TemplateObjectTO to = new TemplateObjectTO(); to.setPath(this.getImageInstallPath()); + to.setFormat(ImageFormat.VHD); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); @@ -253,6 +259,7 @@ public class VolumeTest extends CloudStackTestNGBase { Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId()); } public DataStore createPrimaryDataStore() { @@ -297,7 +304,7 @@ public class VolumeTest extends CloudStackTestNGBase { pool.setPoolType(StoragePoolType.NetworkFilesystem); pool.setPodId(podId); pool.setScope(ScopeType.CLUSTER); - pool.setStorageProviderName("cloudstack primary data store provider"); + pool.setStorageProviderName(DataStoreProvider.DEFAULT_PRIMARY); pool = this.primaryStoreDao.persist(pool); DataStore store = this.dataStoreMgr.getPrimaryDataStore(pool.getId()); return store; diff --git a/engine/storage/integration-test/test/resource/storageContext.xml b/engine/storage/integration-test/test/resource/storageContext.xml index 17f46029726..cc8e3bf9294 100644 --- a/engine/storage/integration-test/test/resource/storageContext.xml +++ b/engine/storage/integration-test/test/resource/storageContext.xml @@ -61,7 +61,6 @@ - @@ -88,4 +87,5 @@ + diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index 270fe47c743..519f6babf3b 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -45,6 +45,11 @@ cloud-framework-ipc ${project.version} + + org.apache.cloudstack + cloud-secondary-storage + ${project.version} + org.apache.cloudstack cloud-engine-api diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 610280f1c04..5a4aaa6ba27 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -24,6 +24,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DownloadCommand; +import org.apache.cloudstack.storage.resource.LocalNfsSecondaryStorageResource; import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; @@ -37,7 +38,7 @@ public class LocalHostEndpoint implements EndPoint { private ScheduledExecutorService executor; ServerResource resource; public LocalHostEndpoint() { -//FIXME resource = new LocalNfsSecondaryStorageResource(); + resource = new LocalNfsSecondaryStorageResource(); executor = Executors.newScheduledThreadPool(10); } @Override diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 727c3f4b082..03a2c28985d 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -853,6 +853,7 @@ public class XenServerStorageProcessor implements StorageProcessor { TemplateObjectTO newVol = new TemplateObjectTO(); newVol.setUuid(snapshotvdi.getUuid(conn)); newVol.setPath(newVol.getUuid()); + newVol.setFormat(ImageFormat.VHD); return new CopyCmdAnswer(newVol); } }catch (Exception e) { diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index eb7d78fc71a..986c3c3a17b 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -179,7 +179,6 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `update_count` bigint unsigned, `updated` datetime, PRIMARY KEY (`id`), - CONSTRAINT `fk_snapshot_store_ref__store_id` FOREIGN KEY `fk_snapshot_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, INDEX `i_snapshot_store_ref__store_id`(`store_id`), CONSTRAINT `fk_snapshot_store_ref__snapshot_id` FOREIGN KEY `fk_snapshot_store_ref__snapshot_id` (`snapshot_id`) REFERENCES `snapshots` (`id`), INDEX `i_snapshot_store_ref__snapshot_id`(`snapshot_id`) From 0b9e0c0f3acd50362f355642e02f9735fdb24376 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sun, 12 May 2013 17:38:33 -0700 Subject: [PATCH 161/303] Override getRootDir in LocalNfsSecondaryStorageResource to make mount successfully on MS side. Now S3 is working. --- engine/storage/pom.xml | 5 +++++ .../cloudstack/storage/LocalHostEndpoint.java | 2 +- .../datastore/PrimaryDataStoreImpl.java | 1 + .../cloud/storage/upload/UploadListener.java | 6 +++++ .../LocalNfsSecondaryStorageResource.java | 22 +++++++++++++++++++ .../resource/NfsSecondaryStorageResource.java | 2 +- 6 files changed, 36 insertions(+), 2 deletions(-) diff --git a/engine/storage/pom.xml b/engine/storage/pom.xml index 519f6babf3b..a82b3ea1cd1 100644 --- a/engine/storage/pom.xml +++ b/engine/storage/pom.xml @@ -56,6 +56,11 @@ ${project.version} + org.apache.cloudstack + cloud-secondary-storage + ${project.version} + + mysql mysql-connector-java ${cs.mysql.version} diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 5a4aaa6ba27..525a507a30b 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -11,7 +11,7 @@ // 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 +// KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index b7db243c706..cea30baae18 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -82,6 +82,7 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Inject StoragePoolHostDao poolHostDao; + @Inject private VolumeDao volumeDao; public PrimaryDataStoreImpl() { diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index d3b7af9f675..c6f273bb93a 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -43,6 +43,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupStorageCommand; +import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadProgressCommand; @@ -56,6 +57,7 @@ import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Type; import com.cloud.storage.UploadVO; import com.cloud.storage.dao.UploadDao; +import com.cloud.storage.download.DownloadListener; import com.cloud.storage.upload.UploadState.UploadEvent; import com.cloud.utils.exception.CloudRuntimeException; @@ -475,6 +477,10 @@ public class UploadListener implements Listener { @Override public void complete(Answer answer) { listener.processAnswers(id, -1, new Answer[] {answer}); + if (listener instanceof DownloadListener) { + DownloadListener dwldListener = (DownloadListener)listener; + dwldListener.getCallback().complete((DownloadAnswer)answer); + } } } } diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java index 53c96ddf518..d783cdd318c 100644 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java @@ -6,12 +6,14 @@ import static java.util.Arrays.asList; import java.io.File; import java.io.InputStream; +import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.concurrent.Executors; import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; @@ -112,6 +114,26 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc } } + @Override + synchronized public String getRootDir(String secUrl) { + try { + URI uri = new URI(secUrl); + String nfsHost = uri.getHost(); + + InetAddress nfsHostAddr = InetAddress.getByName(nfsHost); + String nfsHostIp = nfsHostAddr.getHostAddress(); + String nfsPath = nfsHostIp + ":" + uri.getPath(); + String dir = UUID.nameUUIDFromBytes(nfsPath.getBytes()).toString(); + String root = _parent + "/" + dir; + mount(root, nfsPath); + return root; + } catch (Exception e) { + String msg = "GetRootDir for " + secUrl + " failed due to " + e.toString(); + s_logger.error(msg, e); + throw new CloudRuntimeException(msg); + } + } + @Override protected String mount(String root, String nfsPath) { File file = new File(root); diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 1d5e076d75e..fcd34811c1c 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -158,7 +158,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private String _storageNetmask; private String _storageGateway; private final List nfsIps = new ArrayList(); - private String _parent = "/mnt/SecStorage"; + protected String _parent = "/mnt/SecStorage"; final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; private String createTemplateFromSnapshotXenScript; From 492127c035ceddf9f71c70ba4a9c6f2894cc8319 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Sun, 12 May 2013 18:27:25 -0700 Subject: [PATCH 162/303] fix kvm --- engine/storage/integration-test/pom.xml | 6 ++++ .../storage/test/CloudStackTestNGBase.java | 18 +++++++++-- .../test/DirectAgentManagerSimpleImpl.java | 11 +++++++ .../cloudstack/storage/test/SnapshotTest.java | 4 +-- .../cloudstack/storage/test/VolumeTest.java | 6 ++-- .../snapshot/XenserverSnapshotStrategy.java | 6 +--- .../resource/LibvirtComputingResource.java | 4 +-- .../kvm/storage/KVMStorageProcessor.java | 30 ++++++++----------- scripts/storage/qcow2/managesnapshot.sh | 2 +- utils/src/com/cloud/utils/script/Script.java | 10 ++++++- 10 files changed, 63 insertions(+), 34 deletions(-) diff --git a/engine/storage/integration-test/pom.xml b/engine/storage/integration-test/pom.xml index 56d36ad3a53..8a9dc15579c 100644 --- a/engine/storage/integration-test/pom.xml +++ b/engine/storage/integration-test/pom.xml @@ -67,6 +67,12 @@ cloud-plugin-hypervisor-vmware ${project.version} test + + + org.apache.cloudstack + cloud-plugin-hypervisor-kvm + ${project.version} + test org.apache.cloudstack diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 77b6ec302cc..726ea010c66 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -24,6 +24,7 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.Parameters; import org.testng.annotations.Test; +import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; @@ -38,6 +39,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { private String secondaryStorage; private String imageInstallPath; private String scriptPath; + private HypervisorType hypervisor; private Transaction txn; private String s3AccessKey; @@ -72,11 +74,14 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path", "primary-storage-uuid-want-to-add", "script-path"}) + "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", + "s3-template-bucket", "s3-usehttps", "image-install-path", "primary-storage-uuid-want-to-add", "script-path", + "hypervisor"}) protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, String localStorageUuid, String primaryStorage, String secondaryStorage, String s3_accessKey, String s3_secretKey, String s3_endpoint, String s3_template_bucket, - String s3_usehttps, String imageInstallPath, String primaryStorageUuid, String scriptPath) { + String s3_usehttps, String imageInstallPath, String primaryStorageUuid, String scriptPath, + String hypervisor) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -86,6 +91,7 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.primaryStorageUrl = primaryStorage; this.primaryStorageUuid = primaryStorageUuid; this.imageInstallPath = imageInstallPath; + this.hypervisor = HypervisorType.getType(hypervisor); this.setSecondaryStorage(secondaryStorage); // set S3 parameters this.s3AccessKey = s3_accessKey; @@ -180,5 +186,13 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.scriptPath = scriptPath; } + public HypervisorType getHypervisor() { + return hypervisor; + } + + public void setHypervisor(HypervisorType hypervisor) { + this.hypervisor = hypervisor; + } + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index ac5a69d413e..c11da3d8078 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -50,6 +50,7 @@ import com.cloud.host.HostVO; import com.cloud.host.Status.Event; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.hypervisor.vmware.VmwareServerDiscoverer; import com.cloud.hypervisor.xen.resource.XcpOssResource; import com.cloud.resource.ServerResource; @@ -122,6 +123,16 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa } catch (ConfigurationException e) { logger.debug("Failed to load resource:" + e.toString()); } + } else if (host.getHypervisorType() == HypervisorType.KVM) { + resource = new LibvirtComputingResource(); + try { + params.put("public.network.device", "cloudbr0"); + params.put("private.network.device", "cloudbr0"); + resource.configure(host.getName(), params); + } catch (ConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } else if (host.getHypervisorType() == HypervisorType.VMware) { ClusterVO cluster = clusterDao.findById(host.getClusterId()); String url = clusterDetailsDao.findDetail(cluster.getId(), "url").getValue(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index e772c821d83..d667a787353 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -179,7 +179,7 @@ public class SnapshotTest extends CloudStackTestNGBase { podId = pod.getId(); //create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); - cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setHypervisorType(this.getHypervisor().toString()); cluster.setClusterType(ClusterType.CloudManaged); cluster.setManagedState(ManagedState.Managed); cluster = clusterDao.persist(cluster); @@ -197,7 +197,7 @@ public class SnapshotTest extends CloudStackTestNGBase { host.setPodId(podId); host.setLastPinged(0); host.setResourceState(ResourceState.Enabled); - host.setHypervisorType(HypervisorType.XenServer); + host.setHypervisorType(this.getHypervisor()); host.setClusterId(cluster.getId()); host = hostDao.persist(host); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index c610e505367..76ce4044fb3 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -171,7 +171,7 @@ public class VolumeTest extends CloudStackTestNGBase { podId = pod.getId(); //create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); - cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setHypervisorType(this.getHypervisor().toString()); cluster.setClusterType(ClusterType.CloudManaged); cluster.setManagedState(ManagedState.Managed); cluster = clusterDao.persist(cluster); @@ -189,7 +189,7 @@ public class VolumeTest extends CloudStackTestNGBase { host.setPodId(podId); host.setLastPinged(0); host.setResourceState(ResourceState.Enabled); - host.setHypervisorType(HypervisorType.XenServer); + host.setHypervisorType(this.getHypervisor()); host.setClusterId(cluster.getId()); host = hostDao.persist(host); @@ -320,7 +320,7 @@ public class VolumeTest extends CloudStackTestNGBase { return volume; } - //@Test + @Test public void testCopyBaseImage() { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 171de4c603c..072d14bf07a 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -209,10 +209,6 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { @Override public boolean canHandle(Snapshot snapshot) { - if (snapshot.getHypervisorType() == HypervisorType.XenServer) { - return true; - } else { - return false; - } + return true; } } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index a32d0cce22e..747f337bafb 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -461,7 +461,7 @@ ServerResource { } protected String getDefaultDomrScriptsDir() { - return "scripts/network/domr/kvm"; + return "scripts/network/domr"; } protected String getNetworkDirectSourceMode() { @@ -682,7 +682,7 @@ ServerResource { _localStorageUUID = (String) params.get("local.storage.uuid"); if (_localStorageUUID == null) { - throw new ConfigurationException("local.storage.uuid is not set! Please set this to a valid UUID"); + _localStorageUUID = UUID.nameUUIDFromBytes(_localStoragePath.getBytes()).toString(); } value = (String) params.get("scripts.timeout"); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index c3fc0ec22a4..3bdf4287db0 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -142,7 +142,7 @@ public class KVMStorageProcessor implements StorageProcessor { DataTO destData = cmd.getDestTO(); TemplateObjectTO template = (TemplateObjectTO)srcData; DataStoreTO imageStore = template.getDataStore(); - VolumeObjectTO volume = (VolumeObjectTO)destData; + TemplateObjectTO volume = (TemplateObjectTO)destData; PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); if (!(imageStore instanceof NfsTO)) { @@ -195,10 +195,10 @@ public class KVMStorageProcessor implements StorageProcessor { KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk( tmplVol, UUID.randomUUID().toString(), primaryPool); - VolumeObjectTO newVol = new VolumeObjectTO(); - newVol.setPath(primaryVol.getName()); - newVol.setSize(primaryVol.getSize()); - return new CopyCmdAnswer(newVol); + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(primaryVol.getName()); + newTemplate.setFormat(ImageFormat.QCOW2); + return new CopyCmdAnswer(newTemplate); } catch (CloudRuntimeException e) { return new CopyCmdAnswer(e.toString()); } finally { @@ -273,14 +273,7 @@ public class KVMStorageProcessor implements StorageProcessor { primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); - String templatePath = null; - if (imageStore instanceof NfsTO) { - NfsTO nfsImageStore = (NfsTO)imageStore; - templatePath = nfsImageStore.getUrl(); - } else { - s_logger.debug("Failed to create volume: "); - return new CopyCmdAnswer("Unsupported protocol"); - } + String templatePath = template.getPath(); if(primaryPool.getType() == StoragePoolType.CLVM) { vol = templateToPrimaryDownload(templatePath, primaryPool); @@ -321,9 +314,9 @@ public class KVMStorageProcessor implements StorageProcessor { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); int wait = cmd.getWait(); - TemplateObjectTO template = (TemplateObjectTO)srcData; + TemplateObjectTO template = (TemplateObjectTO)destData; DataStoreTO imageStore = template.getDataStore(); - VolumeObjectTO volume = (VolumeObjectTO)destData; + VolumeObjectTO volume = (VolumeObjectTO)srcData; PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); if (!(imageStore instanceof NfsTO)) { @@ -425,7 +418,7 @@ public class KVMStorageProcessor implements StorageProcessor { loc.save(); TemplateObjectTO newTemplate = new TemplateObjectTO(); - newTemplate.setPath(templateFolder + templateName + ".qcow2"); + newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2"); return new CopyCmdAnswer(newTemplate); } catch (Exception e) { s_logger.debug("Failed to create template from volume: " + e.toString()); @@ -783,8 +776,9 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer createSnapshot(CreateObjectCommand cmd) { - VolumeObjectTO volume = (VolumeObjectTO)cmd.getData(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + SnapshotObjectTO snapshotTO = (SnapshotObjectTO)cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshotTO.getDataStore(); + VolumeObjectTO volume = snapshotTO.getVolume(); String snapshotName = UUID.randomUUID().toString(); String vmName = volume.getVmName(); try { diff --git a/scripts/storage/qcow2/managesnapshot.sh b/scripts/storage/qcow2/managesnapshot.sh index 29b7081290d..30148de66e7 100755 --- a/scripts/storage/qcow2/managesnapshot.sh +++ b/scripts/storage/qcow2/managesnapshot.sh @@ -48,7 +48,7 @@ is_lv() { # And a logical volume lvm lvs "${1}" > /dev/null 2>&1 && return 0 fi - return 1 + return 0 } get_vg() { diff --git a/utils/src/com/cloud/utils/script/Script.java b/utils/src/com/cloud/utils/script/Script.java index 3632bf5ad1b..d3a35916eaf 100755 --- a/utils/src/com/cloud/utils/script/Script.java +++ b/utils/src/com/cloud/utils/script/Script.java @@ -450,7 +450,15 @@ public class Script implements Callable { } - file = new File(System.getProperty("paths.script") + File.separator + path + File.separator + script); + search = System.getProperty("paths.script"); + + search += File.separatorChar + path + File.separator; + do { + search = search.substring(0, search.lastIndexOf(File.separator)); + file = new File(search + File.separator + script); + s_logger.debug("Looking for " + script + " in " + file.getAbsolutePath()); + } while (!file.exists() && search.lastIndexOf(File.separator) != -1); + if (file.exists()) { return file.getAbsolutePath(); } From ff735b4d8190f89ae70de63cbef6049465dfd36a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 11:07:06 -0700 Subject: [PATCH 163/303] Fix a bug in searching for eligible image store when we pass a ZoneScope with scopeId = null. --- .../storage/image/db/ImageStoreDaoImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index d7478293fa2..e6a0e06a8bb 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -81,10 +81,13 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem public List findByScope(ZoneScope scope) { SearchCriteria sc = createSearchCriteria(); sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.Image); - SearchCriteria scc = createSearchCriteria(); - scc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION); - scc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); - sc.addAnd("scope", SearchCriteria.Op.SC, scc); + if (scope.getScopeId() != null) { + SearchCriteria scc = createSearchCriteria(); + scc.addOr("scope", SearchCriteria.Op.EQ, ScopeType.REGION); + scc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + sc.addAnd("scope", SearchCriteria.Op.SC, scc); + } + // we should return all image stores if cross-zone scope is passed (scopeId = null) return listBy(sc); } From c13a6914294172d18ab383bab74d0b6888ea9240 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 11:27:34 -0700 Subject: [PATCH 164/303] Fix some inaccurate logging message in template sync. --- .../cloudstack/storage/image/TemplateServiceImpl.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index bf8155bec4c..a34d2ac39fd 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -282,7 +282,7 @@ public class TemplateServiceImpl implements TemplateService { TemplateProp tmpltInfo = templateInfos.remove(uniqueName); toBeDownloaded.remove(tmplt); if (tmpltStore != null) { - s_logger.info("Template Sync found " + uniqueName + " already in the template host table"); + s_logger.info("Template Sync found " + uniqueName + " already in the image store"); if (tmpltStore.getDownloadState() != Status.DOWNLOADED) { tmpltStore.setErrorString(""); } @@ -335,10 +335,10 @@ public class TemplateServiceImpl implements TemplateService { continue; } if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) { - s_logger.info("Template Sync did not find " + uniqueName + " ready on server " + storeId + ", will request download to start/resume shortly"); + s_logger.info("Template Sync did not find " + uniqueName + " ready on image store " + storeId + ", will request download to start/resume shortly"); } else if (tmpltStore == null) { - s_logger.info("Template Sync did not find " + uniqueName + " on the server " + storeId + ", will request download shortly"); + s_logger.info("Template Sync did not find " + uniqueName + " on the image store " + storeId + ", will request download shortly"); TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); _vmTemplateStoreDao.persist(templtStore); associateTemplateToZone(tmplt.getId(), zoneId); @@ -380,7 +380,6 @@ public class TemplateServiceImpl implements TemplateService { continue; } s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName()); - //TODO: we should pass a callback here TemplateInfo tmpl = _templateFactory.getTemplate(tmplt.getId(), DataStoreRole.Image); createTemplateAsync(tmpl, store, null); } From e6faa47a4b4ab5b9c6490c05db067e32f37d2e45 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 11:36:44 -0700 Subject: [PATCH 165/303] Remove unnecessary state machine entry after refactoring sendMessageAsyncWithListener to use sendMessageAsync. --- .../storage/image/manager/ImageDataManagerImpl.java | 2 -- .../storage/datastore/ObjectInDataStoreManagerImpl.java | 3 --- server/src/com/cloud/storage/upload/UploadListener.java | 6 ------ 3 files changed, 11 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java index d8708308cef..f9dd5a6e2cc 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java @@ -41,8 +41,6 @@ public class ImageDataManagerImpl implements ImageDataManager { stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.DestroyRequested, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationFailed, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationSucceeded, TemplateState.Destroyed); - //TODO: this should not be needed, but it happened during testing where multiple success event is sent to callback - stateMachine.addTransition(TemplateState.Ready, TemplateEvent.OperationSucceeded, TemplateState.Ready); } @Override diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 269ef055f5e..78c3184dde1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -108,9 +108,6 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { State.Destroyed); stateMachines.addTransition(State.Destroying, Event.OperationFailed, State.Destroying); - //TODO: further investigate why an extra event is sent when it is alreay Ready - stateMachines.addTransition(State.Ready, Event.OperationSuccessed, - State.Ready); } @Override diff --git a/server/src/com/cloud/storage/upload/UploadListener.java b/server/src/com/cloud/storage/upload/UploadListener.java index c6f273bb93a..d3b7af9f675 100755 --- a/server/src/com/cloud/storage/upload/UploadListener.java +++ b/server/src/com/cloud/storage/upload/UploadListener.java @@ -43,7 +43,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupStorageCommand; -import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.UploadAnswer; import com.cloud.agent.api.storage.UploadCommand; import com.cloud.agent.api.storage.UploadProgressCommand; @@ -57,7 +56,6 @@ import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Type; import com.cloud.storage.UploadVO; import com.cloud.storage.dao.UploadDao; -import com.cloud.storage.download.DownloadListener; import com.cloud.storage.upload.UploadState.UploadEvent; import com.cloud.utils.exception.CloudRuntimeException; @@ -477,10 +475,6 @@ public class UploadListener implements Listener { @Override public void complete(Answer answer) { listener.processAnswers(id, -1, new Answer[] {answer}); - if (listener instanceof DownloadListener) { - DownloadListener dwldListener = (DownloadListener)listener; - dwldListener.getCallback().complete((DownloadAnswer)answer); - } } } } From 1694c1a502c5dbf43da761648c203495bd5a2dcd Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 13 May 2013 14:40:21 -0700 Subject: [PATCH 166/303] fix download timeout --- .../org/apache/cloudstack/storage/RemoteHostEndPoint.java | 2 +- tools/marvin/marvin/deployDataCenter.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 7a651c009e0..0e88b651098 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -146,7 +146,7 @@ public class RemoteHostEndPoint implements EndPoint { @Override public int getTimeout() { // TODO Auto-generated method stub - return 0; + return -1; } @Override diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index dd6db051e8d..b6d41ffd0bc 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -142,8 +142,10 @@ class deployDataCenters(): secondarycmd.url = secondary.url secondarycmd.provider = secondary.providerName secondarycmd.details = [] - for item in secondary.details: - secondarycmd.details.append(item.__dict__) + + if isinstance(secondary.details, list): + for item in secondary.details: + secondarycmd.details.append(item.__dict__) if secondarycmd.provider == "NFS": secondarycmd.zoneid = zoneId self.apiClient.addImageStore(secondarycmd) From eeb012308cd5e85b6a0f4130c55735756bf266c2 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Fri, 10 May 2013 11:03:54 -0700 Subject: [PATCH 167/303] CLOUDSTACK-2351: object store - UI - zone wizard - add secondary storage step - when provider is S3, add Create NFS Cache Storage option. --- ui/scripts/zoneWizard.js | 62 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index bcad6e8c07e..75a29623e1c 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -810,7 +810,7 @@ if($(this).val() == "VMware") { //$('li[input_sub_group="external"]', $dialogAddCluster).show(); if(dvSwitchEnabled ){ - /* $form.find('.form-item[rel=vSwitchPublicType]').css('display', 'inline-block'); + /* $fields.filter('[rel=vSwitchPublicType]').css('display', 'inline-block'); $form.find('.form-item[rel=vSwitchGuestType]').css('display', 'inline-block'); $form.find('.form-item[rel=vSwitchPublicName]').css('display','inline-block'); @@ -1563,7 +1563,11 @@ $fields.filter('[rel=connectiontimeout]').hide(); $fields.filter('[rel=maxerrorretry]').hide(); $fields.filter('[rel=sockettimeout]').hide(); - + + $fields.filter('[rel=createNfsCache]').hide(); + $fields.filter('[rel=nfsCacheNfsServer]').hide(); + $fields.filter('[rel=nfsCachePath]').hide(); + //Swift $fields.filter('[rel=url]').hide(); $fields.filter('[rel=account]').hide(); @@ -1586,6 +1590,11 @@ $fields.filter('[rel=maxerrorretry]').css('display', 'inline-block'); $fields.filter('[rel=sockettimeout]').css('display', 'inline-block'); + $fields.filter('[rel=createNfsCache]').find('input').attr('checked','checked'); + $fields.filter('[rel=createNfsCache]').css('display', 'inline-block'); + $fields.filter('[rel=nfsCacheNfsServer]').css('display', 'inline-block'); + $fields.filter('[rel=nfsCachePath]').css('display', 'inline-block'); + //Swift $fields.filter('[rel=url]').hide(); $fields.filter('[rel=account]').hide(); @@ -1608,6 +1617,10 @@ $fields.filter('[rel=maxerrorretry]').hide(); $fields.filter('[rel=sockettimeout]').hide(); + $fields.filter('[rel=createNfsCache]').hide(); + $fields.filter('[rel=nfsCacheNfsServer]').hide(); + $fields.filter('[rel=nfsCachePath]').hide(); + //Swift $fields.filter('[rel=url]').css('display', 'inline-block'); $fields.filter('[rel=account]').css('display', 'inline-block'); @@ -1650,6 +1663,22 @@ connectiontimeout: { label: 'label.s3.connection_timeout' }, maxerrorretry: { label: 'label.s3.max_error_retry' }, sockettimeout: { label: 'label.s3.socket_timeout' }, + + createNfsCache: { + label: 'Create NFS Cache Storage', + isBoolean: true, + isChecked: true + }, + nfsCacheNfsServer: { + dependsOn: 'createNfsCache', + label: 'label.nfs.server', + validation: { required: true } + }, + nfsCachePath: { + dependsOn: 'createNfsCache', + label: 'label.path', + validation: { required: true } + }, //S3 (end) @@ -3587,11 +3616,36 @@ }) }); }, - error: function(json) { + error: function(XMLHttpResponse) { var errorMsg = parseXMLHttpResponse(XMLHttpResponse); error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); } }); + + if(args.data.secondaryStorage.createNfsCache == 'on') { + var zoneid = args.data.secondaryStorage.nfsCacheZoneid; + var nfs_server = args.data.secondaryStorage.nfsCacheNfsServer; + var path = args.data.secondaryStorage.nfsCachePath; + var url = nfsURL(nfs_server, path); + + var nfsCacheData = { + provider: 'NFS', + zoneid: args.data.returnedZone.id, + url: url + }; + + $.ajax({ + url: createURL('createCacheStore'), + data: nfsCacheData, + success: function(json) { + //do nothing + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); + } + }); + } } else if(args.data.secondaryStorage.provider == 'Swift') { $.ajax({ @@ -3613,7 +3667,7 @@ }) }); }, - error: function(json) { + error: function(XMLHttpResponse) { var errorMsg = parseXMLHttpResponse(XMLHttpResponse); error('addSecondaryStorage', errorMsg, { fn: 'addSecondaryStorage', args: args }); } From 5341f299ff0271a2216f087a1b589b642cc3e9cd Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 15:33:59 -0700 Subject: [PATCH 168/303] We still need the hack of Ready to Ready transition for NFS. --- .../cloudstack/storage/image/manager/ImageDataManagerImpl.java | 2 ++ .../storage/datastore/ObjectInDataStoreManagerImpl.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java index f9dd5a6e2cc..d8708308cef 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java @@ -41,6 +41,8 @@ public class ImageDataManagerImpl implements ImageDataManager { stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.DestroyRequested, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationFailed, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationSucceeded, TemplateState.Destroyed); + //TODO: this should not be needed, but it happened during testing where multiple success event is sent to callback + stateMachine.addTransition(TemplateState.Ready, TemplateEvent.OperationSucceeded, TemplateState.Ready); } @Override diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 78c3184dde1..10c94e421f9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -108,6 +108,9 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { State.Destroyed); stateMachines.addTransition(State.Destroying, Event.OperationFailed, State.Destroying); + //TODO: further investigate why an extra event is sent when it is alreay Ready for DownloadListener + stateMachines.addTransition(State.Ready, Event.OperationSuccessed, + State.Ready); } @Override From dafe2654b6599482d49a16ee8888a125cfecd988 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 15:37:34 -0700 Subject: [PATCH 169/303] Fix default devcloud.cfg --- tools/devcloud/devcloud.cfg | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/devcloud/devcloud.cfg b/tools/devcloud/devcloud.cfg index 67879569e03..4432fb20d77 100644 --- a/tools/devcloud/devcloud.cfg +++ b/tools/devcloud/devcloud.cfg @@ -86,9 +86,8 @@ { "url": "nfs://192.168.56.10/opt/storage/secondary", "providerName": "NFS", - "details": { - } - } + "details": [ ] + } ] } ], From 9777e56e8ea4518d8853e49bc08d8c482490a45d Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 15:45:47 -0700 Subject: [PATCH 170/303] Update built-in template size in vm_template table. --- .../apache/cloudstack/storage/image/TemplateServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index a34d2ac39fd..7419e9f5521 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -305,6 +305,10 @@ public class TemplateServiceImpl implements TemplateService { tmpltStore.setSize(tmpltInfo.getSize()); tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); tmpltStore.setLastUpdated(new Date()); + // update size in vm_template table + VMTemplateVO tmlpt = _templateDao.findById(tmplt.getId()); + tmlpt.setSize(tmpltInfo.getSize()); + _templateDao.update(tmplt.getId(), tmlpt); if (tmpltInfo.getSize() > 0) { long accountId = tmplt.getAccountId(); From b082e23af30d784043f10ff215c2276fd916f73e Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Mon, 13 May 2013 16:21:43 -0700 Subject: [PATCH 171/303] CLOUDSTACK-2351: object store - UI - restore UI change that was overwriten by the sync from master branch. --- ui/scripts/system.js | 373 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 329 insertions(+), 44 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 34ba64c917d..7b4cb585b85 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -279,12 +279,12 @@ pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property. }; $.ajax({ - url: createURL('listHosts'), + url: createURL('listImageStores'), data: data2, success: function(json) { dataFns.systemVmCount($.extend(data, { - secondaryStorageCount: json.listhostsresponse.count ? - json.listhostsresponse.count : 0 + secondaryStorageCount: json.listimagestoreresponse.imagestore ? + json.listimagestoreresponse.count : 0 })); } }); @@ -5762,10 +5762,10 @@ }; $.ajax({ - url: createURL('listHosts' + searchByArgs), + url: createURL('listImageStores' + searchByArgs), data: data, success: function (json) { - args.response.success({ data: json.listhostsresponse.host }); + args.response.success({ data: json.listimagestoreresponse.imagestore }); }, error: function (json) { args.response.error(parseXMLHttpResponse(json)); @@ -10902,11 +10902,11 @@ array1.push("&zoneid=" + args.context.zones[0].id); $.ajax({ - url: createURL("listHosts&type=SecondaryStorage&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + url: createURL("listImageStores&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), dataType: "json", async: true, success: function(json) { - var items = json.listhostsresponse.host; + var items = json.listimagestoreresponse.imagestore; args.response.success({ actionFilter: secondarystorageActionfilter, data:items @@ -10921,29 +10921,150 @@ createForm: { title: 'label.add.secondary.storage', - fields: { + + fields: { + provider: { + label: 'Provider', + select: function(args){ + $.ajax({ + url: createURL('listStorageProviders'), + data: { + type: 'image' + }, + success: function(json){ + var objs = json.liststorageprovidersresponse.dataStoreProvider; + var items = []; + if(objs != null) { + for(var i = 0; i < objs.length; i++){ + if(objs[i].name == 'NFS') + items.unshift({id: objs[i].name, description: objs[i].name}); + else + items.push({id: objs[i].name, description: objs[i].name}); + } + } + args.response.success({ + data: items + }); + + args.$select.change(function() { + var $form = $(this).closest('form'); + if($(this).val() == "NFS") { + //NFS + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if ($(this).val() == "S3") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); + $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); + $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); + $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); + $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); + $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + + $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked','checked'); + $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); + + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if($(this).val() == "Swift") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + + //Swift + $form.find('.form-item[rel=url]').css('display', 'inline-block'); + $form.find('.form-item[rel=account]').css('display', 'inline-block'); + $form.find('.form-item[rel=username]').css('display', 'inline-block'); + $form.find('.form-item[rel=key]').css('display', 'inline-block'); + } + }); + + args.$select.change(); + } + }); + } + }, + + + //NFS (begin) zoneid: { label: 'Zone', docID: 'helpSecondaryStorageZone', validation: { required: true }, - select: function(args) { - var data = args.context.zones ? - { id: args.context.zones[0].id } : { listAll: true }; - + select: function(args) { $.ajax({ url: createURL('listZones'), - data: data, + data: { + listAll: true + }, success: function(json) { var zones = json.listzonesresponse.zone; - args.response.success({ - data: $.map(zones, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } } }); } @@ -10957,30 +11078,194 @@ label: 'label.path', docID: 'helpSecondaryStoragePath', validation: { required: true } - } + }, + //NFS (end) + + + //S3 (begin) + accesskey: { label: 'label.s3.access_key', validation: { required: true } }, + secretkey: { label: 'label.s3.secret_key', validation: { required: true} }, + bucket: { label: 'label.s3.bucket', validation: { required: true} }, + endpoint: { label: 'label.s3.endpoint' }, + usehttps: { + label: 'label.s3.use_https', + isEditable: true, + isBoolean: true, + isChecked: true, + converter:cloudStack.converters.toBooleanText + }, + connectiontimeout: { label: 'label.s3.connection_timeout' }, + maxerrorretry: { label: 'label.s3.max_error_retry' }, + sockettimeout: { label: 'label.s3.socket_timeout' }, + + createNfsCache: { + label: 'Create NFS Cache Storage', + isBoolean: true, + isChecked: true + }, + nfsCacheZoneid: { + dependsOn: 'createNfsCache', + label: 'Zone', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } + } + }); + } + }, + nfsCacheNfsServer: { + dependsOn: 'createNfsCache', + label: 'label.nfs.server', + validation: { required: true } + }, + nfsCachePath: { + dependsOn: 'createNfsCache', + label: 'label.path', + validation: { required: true } + }, + //S3 (end) + + + //Swift (begin) + url: { label: 'label.url', validation: { required: true } }, + account: { label: 'label.account' }, + username: { label: 'label.username' }, + key: { label: 'label.key' } + //Swift (end) } }, action: function(args) { - var zoneId = args.data.zoneid; - var nfs_server = args.data.nfsServer; - var path = args.data.path; - var url = nfsURL(nfs_server, path); - - $.ajax({ - url: createURL("addSecondaryStorage&zoneId=" + zoneId + "&url=" + todb(url)), - dataType: "json", - success: function(json) { - var item = json.addsecondarystorageresponse.secondarystorage; - args.response.success({ - data:item - }); - }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - args.response.error(errorMsg); - } - }); + if(args.data.provider == 'NFS') { + var zoneid = args.data.zoneid; + var nfs_server = args.data.nfsServer; + var path = args.data.path; + var url = nfsURL(nfs_server, path); + + var data = { + provider: args.data.provider, + zoneid: zoneid, + url: url + }; + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + args.response.error(errorMsg); + } + }); + } + else if(args.data.provider == 'S3') { + $.ajax({ + url: createURL('addImageStore'), + data: { + provider: args.data.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.bucket, + 'details[3].key': 'endpoint', + 'details[3].value': args.data.endpoint, + 'details[4].key': 'usehttps', + 'details[4].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false'), + 'details[5].key': 'connectiontimeout', + 'details[5].value': args.data.connectiontimeout, + 'details[6].key': 'maxerrorretry', + 'details[6].value': args.data.maxerrorretry, + 'details[7].key': 'sockettimeout', + 'details[7].value': args.data.sockettimeout + }, + success: function(json) { + havingS3 = true; + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + + if(args.data.createNfsCache == 'on') { + var zoneid = args.data.nfsCacheZoneid; + var nfs_server = args.data.nfsCacheNfsServer; + var path = args.data.nfsCachePath; + var url = nfsURL(nfs_server, path); + + var nfsCacheData = { + provider: 'NFS', + zoneid: zoneid, + url: url + }; + + $.ajax({ + url: createURL('createCacheStore'), + data: nfsCacheData, + success: function(json) { + //do nothing + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + } + else if(args.data.provider == 'Swift') { + $.ajax({ + url: createURL('addImageStore'), + data: { + provider: args.data.provider, + url: args.data.url, + 'details[0].key': 'account', + 'details[0].value': args.data.account, + 'details[1].key': 'username', + 'details[1].value': args.data.username, + 'details[2].key': 'key', + 'details[2].value': args.data.key + }, + success: function(json) { + havingSwift = true; + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } }, notification: { @@ -11015,7 +11300,7 @@ }, action: function(args) { $.ajax({ - url: createURL("deleteHost&id=" + args.context.secondarystorages[0].id), + url: createURL("deleteImageStore&id=" + args.context.secondarystorages[0].id), dataType: "json", async: true, success: function(json) { @@ -11045,11 +11330,11 @@ dataProvider: function(args) { $.ajax({ - url: createURL("listHosts&type=SecondaryStorage&id=" + args.context.secondarystorages[0].id), + url: createURL("listImageStores&id=" + args.context.secondarystorages[0].id), dataType: "json", async: true, success: function(json) { - var item = json.listhostsresponse.host[0]; + var item = json.listimagestoreresponse.imagestore[0]; args.response.success({ actionFilter: secondarystorageActionfilter, data:item From a7480530f7f8c2929fd7df7dcf020e245322e6cf Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 13 May 2013 16:22:19 -0700 Subject: [PATCH 172/303] fix RAT --- .../LocalNfsSecondaryStorageResource.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java index d783cdd318c..7322a81353c 100644 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java @@ -1,3 +1,19 @@ +// 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.resource; import static com.cloud.utils.StringUtils.join; From 0ce01e56dbb4ec83383f43932da5a66f1b7280c6 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Mon, 13 May 2013 16:45:03 -0700 Subject: [PATCH 173/303] set template size when creating template from snapshot --- .../apache/cloudstack/storage/to/TemplateObjectTO.java | 9 +++++++++ .../cloudstack/storage/image/store/TemplateObject.java | 1 + .../storage/resource/NfsSecondaryStorageResource.java | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 14577ef2c00..9e7e9ef452f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -39,6 +39,7 @@ public class TemplateObjectTO implements DataTO { private DataStoreTO imageDataStore; private String name; private String guestOsType; + private Long size; public TemplateObjectTO() { @@ -159,4 +160,12 @@ public class TemplateObjectTO implements DataTO { public void setGuestOsType(String guestOsType) { this.guestOsType = guestOsType; } + + public Long getSize() { + return size; + } + + public void setSize(Long size) { + this.size = size; + } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 12e29e78163..cd94704d490 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -226,6 +226,7 @@ public class TemplateObject implements TemplateInfo { if (this.getDataStore().getRole() == DataStoreRole.Image) { VMTemplateVO templateVO = this.imageDao.findById(this.getId()); templateVO.setFormat(newTemplate.getFormat()); + templateVO.setSize(newTemplate.getSize()); this.imageDao.update(templateVO.getId(), templateVO); } } diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index fcd34811c1c..c93b99a1f11 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -367,10 +367,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S loc.create(1, true, templateName); loc.addFormat(info); loc.save(); - + TemplateProp prop = loc.getTemplateInfo(); TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(destData.getPath() + File.separator + templateName); newTemplate.setFormat(ImageFormat.VHD); + newTemplate.setSize(prop.getSize()); return new CopyCmdAnswer(newTemplate); } catch (ConfigurationException e) { s_logger.debug("Failed to create template from snapshot: " + e.toString()); From 3424ac86ad5cbf1a06f17e35bbb4fac5a8e61101 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 17:45:22 -0700 Subject: [PATCH 174/303] Fix size issue for template created from snapshot. --- .../storage/template/TemplateLocation.java | 70 ++++++++++--------- .../storage/image/store/TemplateObject.java | 1 + 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java index eb7a6ec7e62..34626e52bda 100644 --- a/core/src/com/cloud/storage/template/TemplateLocation.java +++ b/core/src/com/cloud/storage/template/TemplateLocation.java @@ -35,17 +35,17 @@ import com.cloud.utils.NumbersUtil; public class TemplateLocation { private static final Logger s_logger = Logger.getLogger(TemplateLocation.class); public final static String Filename = "template.properties"; - + StorageLayer _storage; String _templatePath; boolean _isCorrupted; ResourceType _resourceType = ResourceType.TEMPLATE; - + File _file; Properties _props; - + ArrayList _formats; - + public TemplateLocation(StorageLayer storage, String templatePath) { _storage = storage; _templatePath = templatePath; @@ -63,16 +63,16 @@ public class TemplateLocation { } _isCorrupted = false; } - + public boolean create(long id, boolean isPublic, String uniqueName) throws IOException { boolean result = load(); _props.setProperty("id", Long.toString(id)); _props.setProperty("public", Boolean.toString(isPublic)); _props.setProperty("uniquename", uniqueName); - + return result; } - + public boolean purge() { boolean purged = true; String[] files = _storage.listFiles(_templatePath); @@ -85,10 +85,10 @@ public class TemplateLocation { s_logger.debug((r ? "R" : "Unable to r") + "emove " + file); } } - + return purged; } - + public boolean load() throws IOException { FileInputStream strm = null; try { @@ -102,7 +102,7 @@ public class TemplateLocation { } } } - + for (ImageFormat format : ImageFormat.values()) { String ext = _props.getProperty(format.getFileExtension()); if (ext != null) { @@ -115,22 +115,22 @@ public class TemplateLocation { info.size = NumbersUtil.parseLong(_props.getProperty(format.getFileExtension() + ".size"), -1); _props.setProperty("physicalSize", Long.toString(info.size)); info.virtualSize = NumbersUtil.parseLong(_props.getProperty(format.getFileExtension() + ".virtualsize"), -1); - _formats.add(info); - + _formats.add(info); + if (!checkFormatValidity(info)) { _isCorrupted = true; s_logger.warn("Cleaning up inconsistent information for " + format); - } + } } } - + if (_props.getProperty("uniquename") == null || _props.getProperty("virtualsize") == null) { return false; } - + return (_formats.size() > 0); } - + public boolean save() { for (FormatInfo info : _formats) { _props.setProperty(info.format.getFileExtension(), "true"); @@ -152,60 +152,64 @@ public class TemplateLocation { } catch (IOException e) { } } - } + } return true; } - + public TemplateProp getTemplateInfo() { - TemplateProp tmplInfo = new TemplateProp(); + TemplateProp tmplInfo = new TemplateProp(); tmplInfo.id = Long.parseLong(_props.getProperty("id")); tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename"); if (_resourceType == ResourceType.VOLUME){ - tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("volumes")); + tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("volumes")); }else { tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("template")); } tmplInfo.isCorrupted = _isCorrupted; tmplInfo.isPublic = Boolean.parseBoolean(_props.getProperty("public")); tmplInfo.templateName = _props.getProperty("uniquename"); - tmplInfo.size = Long.parseLong(_props.getProperty("virtualsize")); - tmplInfo.physicalSize = Long.parseLong(_props.getProperty("physicalSize")); - + if (_props.getProperty("virtualsize") != null) { + tmplInfo.size = Long.parseLong(_props.getProperty("virtualsize")); + } + if (_props.getProperty("physicalSize") != null) { + tmplInfo.physicalSize = Long.parseLong(_props.getProperty("physicalSize")); + } + return tmplInfo; } - - + + public FormatInfo getFormat(ImageFormat format) { for (FormatInfo info : _formats) { if (info.format == format) { return info; } } - + return null; } - + public boolean addFormat(FormatInfo newInfo) { deleteFormat(newInfo.format); - + if (!checkFormatValidity(newInfo)) { s_logger.warn("Format is invalid "); return false; } - + _props.setProperty("virtualsize", Long.toString(newInfo.virtualSize)); _formats.add(newInfo); return true; } - + public void updateVirtualSize(long virtualSize) { _props.setProperty("virtualsize", Long.toString(virtualSize)); } - + protected boolean checkFormatValidity(FormatInfo info) { return (info.format != null && info.size > 0 && info.virtualSize > 0 && info.filename != null); } - + protected FormatInfo deleteFormat(ImageFormat format) { Iterator it = _formats.iterator(); while (it.hasNext()) { @@ -219,7 +223,7 @@ public class TemplateLocation { return info; } } - + return null; } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index cd94704d490..a94716e5e31 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -222,6 +222,7 @@ public class TemplateObject implements TemplateInfo { templateStoreRef.setInstallPath(newTemplate.getPath()); templateStoreRef.setDownloadPercent(100); templateStoreRef.setDownloadState(Status.DOWNLOADED); + templateStoreRef.setSize(newTemplate.getSize()); templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); if (this.getDataStore().getRole() == DataStoreRole.Image) { VMTemplateVO templateVO = this.imageDao.findById(this.getId()); From bbdab9806d55b1fe04a34de1896cd7dd6f6b883e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 13 May 2013 22:09:06 -0700 Subject: [PATCH 175/303] CLOUDSTACK-2470: listVolume throws db exception. --- setup/db/db/schema-410to420.sql | 101 +------------------------------- 1 file changed, 1 insertion(+), 100 deletions(-) diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 986c3c3a17b..b0ac31f10e0 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1350,106 +1350,7 @@ CREATE VIEW `cloud`.`template_view` AS and (resource_tags.resource_type = 'Template' or resource_tags.resource_type='ISO'); -DROP VIEW IF EXISTS `cloud`.`volume_view`; -CREATE VIEW `cloud`.`volume_view` AS - select - volumes.id, - volumes.uuid, - volumes.name, - volumes.device_id, - volumes.volume_type, - volumes.size, - volumes.created, - volumes.state, - volumes.attached, - volumes.removed, - volumes.pod_id, - account.id account_id, - account.uuid account_uuid, - account.account_name account_name, - account.type account_type, - domain.id domain_id, - domain.uuid domain_uuid, - domain.name domain_name, - domain.path domain_path, - projects.id project_id, - projects.uuid project_uuid, - projects.name project_name, - data_center.id data_center_id, - data_center.uuid data_center_uuid, - data_center.name data_center_name, - vm_instance.id vm_id, - vm_instance.uuid vm_uuid, - vm_instance.name vm_name, - vm_instance.state vm_state, - vm_instance.vm_type, - user_vm.display_name vm_display_name, - volume_store_ref.size volume_host_size, - volume_store_ref.created volume_host_created, - volume_store_ref.format, - volume_store_ref.download_pct, - volume_store_ref.download_state, - volume_store_ref.error_str, - disk_offering.id disk_offering_id, - disk_offering.uuid disk_offering_uuid, - disk_offering.name disk_offering_name, - disk_offering.display_text disk_offering_display_text, - disk_offering.use_local_storage, - disk_offering.system_use, - storage_pool.id pool_id, - storage_pool.uuid pool_uuid, - storage_pool.name pool_name, - cluster.hypervisor_type, - vm_template.id template_id, - vm_template.uuid template_uuid, - vm_template.extractable, - vm_template.type template_type, - resource_tags.id tag_id, - resource_tags.uuid tag_uuid, - resource_tags.key tag_key, - resource_tags.value tag_value, - resource_tags.domain_id tag_domain_id, - resource_tags.account_id tag_account_id, - resource_tags.resource_id tag_resource_id, - resource_tags.resource_uuid tag_resource_uuid, - resource_tags.resource_type tag_resource_type, - resource_tags.customer tag_customer, - async_job.id job_id, - async_job.uuid job_uuid, - async_job.job_status job_status, - async_job.account_id job_account_id - from - `cloud`.`volumes` - inner join - `cloud`.`account` ON volumes.account_id = account.id - inner join - `cloud`.`domain` ON volumes.domain_id = domain.id - left join - `cloud`.`projects` ON projects.project_account_id = account.id - left join - `cloud`.`data_center` ON volumes.data_center_id = data_center.id - left join - `cloud`.`vm_instance` ON volumes.instance_id = vm_instance.id - left join - `cloud`.`user_vm` ON user_vm.id = vm_instance.id - left join - `cloud`.`volume_store_ref` ON volumes.id = volume_store_ref.volume_id - and volumes.data_center_id = volume_store_ref.zone_id - left join - `cloud`.`disk_offering` ON volumes.disk_offering_id = disk_offering.id - left join - `cloud`.`storage_pool` ON volumes.pool_id = storage_pool.id - left join - `cloud`.`cluster` ON storage_pool.cluster_id = cluster.id - left join - `cloud`.`vm_template` ON volumes.template_id = vm_template.id - left join - `cloud`.`resource_tags` ON resource_tags.resource_id = volumes.id - and resource_tags.resource_type = 'Volume' - left join - `cloud`.`async_job` ON async_job.instance_id = volumes.id - and async_job.instance_type = 'Volume' - and async_job.job_status = 0; + INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.apiserver.address', 'http://localhost:8081', 'Specify the address at which the Midonet API server can be contacted (if using Midonet)'); INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.providerrouter.id', 'd7c5e6a3-e2f4-426b-b728-b7ce6a0448e5', 'Specifies the UUID of the Midonet provider router (if using Midonet)'); From 2102ede2e73c49e69a402c7b0f97a44b77e41e8f Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 11:42:24 -0700 Subject: [PATCH 176/303] Fix CLOUDSTACK-2469: default template is not downloaded. --- .../storage/image/TemplateServiceImpl.java | 17 +++++++++++------ .../template/HypervisorTemplateAdapter.java | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 7419e9f5521..a9302b33d57 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -340,11 +340,15 @@ public class TemplateServiceImpl implements TemplateService { } if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) { s_logger.info("Template Sync did not find " + uniqueName + " ready on image store " + storeId + ", will request download to start/resume shortly"); + s_logger.info("Removing template " + uniqueName + " from template store table"); + // remove those leftover entries + _vmTemplateStoreDao.remove(tmpltStore.getId()); } else if (tmpltStore == null) { s_logger.info("Template Sync did not find " + uniqueName + " on the image store " + storeId + ", will request download shortly"); - TemplateDataStoreVO templtStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 0, Status.NOT_DOWNLOADED, null, null, null, null, tmplt.getUrl()); - _vmTemplateStoreDao.persist(templtStore); + // persist template_zone_ref table + // TODO: we may have some bugs in removing these entries in case of failure, maybe we should pass another callback below in invoking createTemplateAsync + // to just clear those entries. associateTemplateToZone(tmplt.getId(), zoneId); } @@ -370,20 +374,21 @@ public class TemplateServiceImpl implements TemplateService { continue; } // check if there is a record for this template in this store - TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); + TemplateDataStoreVO tmpltStoreVO = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); // if this is private template, and there is no record for this // template in this store, skip + // TODO: don't understand this logic. What happens if we have a record for this template, still download? if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) { - if (tmpltHost == null) { + if (tmpltStoreVO == null) { continue; } } if (availHypers.contains(tmplt.getHypervisorType())) { - if (tmpltHost != null ) { + if (tmpltStoreVO != null && tmpltStoreVO.getDownloadState() == Status.DOWNLOADED) { continue; } - s_logger.debug("Template " + tmplt.getName() + " needs to be downloaded to " + store.getName()); + s_logger.info("Downloading template " + tmplt.getUniqueName() + " to image store " + store.getName()); TemplateInfo tmpl = _templateFactory.getTemplate(tmplt.getId(), DataStoreRole.Image); createTemplateAsync(tmpl, store, null); } diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index b2a49a3b18c..74bae35ef75 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -169,7 +169,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { @Override public VMTemplateVO create(TemplateProfile profile) { - // persist entry in vm_template, vm_template_details and template_zone_ref tables + // persist entry in vm_template, vm_template_details and template_zone_ref tables, not that entry at template_store_ref is not created here, and created in createTemplateAsync. VMTemplateVO template = persistTemplate(profile); if (template == null) { From 12583bbffc7e27b62e33ba86b44acef40a8594c4 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 14 May 2013 10:52:04 -0700 Subject: [PATCH 177/303] snapshot path is accountId + volumeid --- .../storage/datastore/ObjectInDataStoreManagerImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index 10c94e421f9..f2ec961c6e1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; 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.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; @@ -140,12 +141,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { ts = templateDataStoreDao.persist(ts); break; case SNAPSHOT: + SnapshotInfo snapshot = (SnapshotInfo)obj; SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); ss.setSnapshotId(obj.getId()); ss.setDataStoreId(dataStore.getId()); ss.setRole(dataStore.getRole()); ss.setRole(dataStore.getRole()); - ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + snapshot.getVolumeId()); ss.setState(ObjectInDataStoreStateMachine.State.Allocated); ss = snapshotDataStoreDao.persist(ss); break; From 87af4ddab06327787d77f1eab3bdc9939a523e30 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 14:45:35 -0700 Subject: [PATCH 178/303] Only download eligible system template for S3 image store. --- .../storage/image/TemplateServiceImpl.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index a9302b33d57..9bd7cb7b4a6 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -185,11 +185,27 @@ public class TemplateServiceImpl implements TemplateService { toBeDownloaded.add(rtngTmplt); } + List availHypers = _clusterDao.getAvailableHypervisorInZone(store.getScope().getScopeId()); + if (availHypers.isEmpty()) { + /* + * This is for cloudzone, local secondary storage resource + * started before cluster created + */ + availHypers.add(HypervisorType.KVM); + } + /* Baremetal need not to download any template */ + availHypers.remove(HypervisorType.BareMetal); + availHypers.add(HypervisorType.None); // bug 9809: resume ISO + // download. + for (VMTemplateVO template : toBeDownloaded) { - TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); - if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { - TemplateInfo tmplt = _templateFactory.getTemplate(template.getId(), DataStoreRole.Image); - createTemplateAsync(tmplt, store, null); + if (availHypers.contains(template.getHypervisorType())) { + // only download sys template applicable for current hypervisor + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); + if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { + TemplateInfo tmplt = _templateFactory.getTemplate(template.getId(), DataStoreRole.Image); + createTemplateAsync(tmplt, store, null); + } } } } From 03c255068b8febcb4eef5559a7a676caeca8a59e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 14:47:16 -0700 Subject: [PATCH 179/303] Fix CLOUDSTACK-2484: not able to deploy VM from registered ISO. --- .../com/cloud/api/query/QueryManagerImpl.java | 271 +++++++++--------- .../cloud/template/TemplateAdapterBase.java | 9 +- 2 files changed, 140 insertions(+), 140 deletions(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index ab07f4feb12..f7fea53f55d 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -855,11 +855,11 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { sc.setParameters("stateNEQ", "Destroyed"); } } - + if (zoneType != null) { sc.setParameters("dataCenterType", zoneType); } - + if (pod != null) { sc.setParameters("podId", pod); @@ -1112,7 +1112,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if (zoneType != null) { sc.setParameters("dataCenterType", zoneType); } - + if (pod != null) { sc.setParameters("podId", pod); } @@ -2346,7 +2346,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { if(networkType != null) sc.addAnd("networkType", SearchCriteria.Op.EQ, networkType); - + if (id != null) { sc.addAnd("id", SearchCriteria.Op.EQ, id); } else if (name != null) { @@ -2519,9 +2519,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { cmd.getZoneId(), hypervisorType, showDomr, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); } - private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, TemplateFilter templateFilter, boolean isIso, - Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean showDomr, boolean onlyReady, - List permittedAccounts, Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { + private Pair, Integer> searchForTemplatesInternal(Long templateId, String name, String keyword, + TemplateFilter templateFilter, boolean isIso, Boolean bootable, Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, + boolean showDomr, boolean onlyReady, List permittedAccounts, Account caller, + ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { VMTemplateVO template = null; // verify templateId parameter @@ -2571,167 +2572,171 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { // add criteria for project or not if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); - } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly){ + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); } // add criteria for domain path in case of domain admin - if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && - (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { - sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); - } + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) + && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); + } - List relatedDomainIds = new ArrayList(); - List permittedAccountIds = new ArrayList(); - if (!permittedAccounts.isEmpty()) { - for (Account account : permittedAccounts) { - permittedAccountIds.add(account.getId()); - DomainVO accountDomain = _domainDao.findById(account.getDomainId()); + List relatedDomainIds = new ArrayList(); + List permittedAccountIds = new ArrayList(); + if (!permittedAccounts.isEmpty()) { + for (Account account : permittedAccounts) { + permittedAccountIds.add(account.getId()); + DomainVO accountDomain = _domainDao.findById(account.getDomainId()); - // get all parent domain ID's all the way till root domain - DomainVO domainTreeNode = accountDomain; + // get all parent domain ID's all the way till root domain + DomainVO domainTreeNode = accountDomain; + relatedDomainIds.add(domainTreeNode.getId()); + while (domainTreeNode.getParent() != null) { + domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); relatedDomainIds.add(domainTreeNode.getId()); - while (domainTreeNode.getParent() != null ){ - domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); - relatedDomainIds.add(domainTreeNode.getId()); - } + } - // get all child domain ID's - if (_accountMgr.isAdmin(account.getType()) ) { - List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); - for (DomainVO childDomain : allChildDomains) { - relatedDomainIds.add(childDomain.getId()); - } + // get all child domain ID's + if (_accountMgr.isAdmin(account.getType())) { + List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); + for (DomainVO childDomain : allChildDomains) { + relatedDomainIds.add(childDomain.getId()); } } } + } - // add hypervisor criteria - if ( hypers != null && !hypers.isEmpty()){ + if (!isIso) { + // add hypervisor criteria for template case + if (hypers != null && !hypers.isEmpty()) { String[] relatedHypers = new String[hypers.size()]; - for (int i = 0; i < hypers.size(); i++){ + for (int i = 0; i < hypers.size(); i++) { relatedHypers[i] = hypers.get(i).toString(); } sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers); } + } - // control different template filters - if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { - sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); - if ( templateFilter == TemplateFilter.featured){ + // control different template filters + if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { + sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); + if (templateFilter == TemplateFilter.featured) { sc.addAnd("featured", SearchCriteria.Op.EQ, true); - } - else{ - sc.addAnd("featured", SearchCriteria.Op.EQ, false); - } - if (!permittedAccounts.isEmpty()) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); - scc.addOr("domainId", SearchCriteria.Op.NULL); - sc.addAnd("domainId", SearchCriteria.Op.SC, scc); + } else { + sc.addAnd("featured", SearchCriteria.Op.EQ, false); + } + if (!permittedAccounts.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); + scc.addOr("domainId", SearchCriteria.Op.NULL); + sc.addAnd("domainId", SearchCriteria.Op.SC, scc); - if (!_accountMgr.isAdmin(caller.getType())){ - // for non-root users, we should only show featured and community templates that they can see - sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - } - } - } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable ) { - if ( !permittedAccounts.isEmpty()){ + if (!_accountMgr.isAdmin(caller.getType())) { + // for non-root users, we should only show featured and + // community templates that they can see sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); } - } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + } + } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { + if (!permittedAccounts.isEmpty()) { + sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + sc.addAnd("accountId", SearchCriteria.Op.SC, scc); + } else if (templateFilter == TemplateFilter.executable) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); + if (!permittedAccounts.isEmpty()) { scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - sc.addAnd("accountId", SearchCriteria.Op.SC, scc); - } else if (templateFilter == TemplateFilter.executable ) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); - if ( !permittedAccounts.isEmpty()){ - scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + } + sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); + } + + // add tags criteria + if (tags != null && !tags.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + int count = 0; + for (String key : tags.keySet()) { + SearchCriteria scTag = _templateJoinDao.createSearchCriteria(); + scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); + scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); + if (isIso) { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.ISO); + } else { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.Template); } - sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); + scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); + count++; } + sc.addAnd("tagKey", SearchCriteria.Op.SC, scc); + } - // add tags criteria - if (tags != null && !tags.isEmpty()) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - int count = 0; - for (String key : tags.keySet()) { - SearchCriteria scTag = _templateJoinDao.createSearchCriteria(); - scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); - scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); - if ( isIso){ - scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.ISO); - } else { - scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.Template); - } - scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); - count++; - } - sc.addAnd("tagKey", SearchCriteria.Op.SC, scc); - } + // other criteria + if (templateId != null) { + sc.addAnd("id", SearchCriteria.Op.EQ, templateId); + } else if (keyword != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + } else if (name != null) { + sc.addAnd("name", SearchCriteria.Op.EQ, name); + } - // other criteria - if (templateId != null){ - sc.addAnd("id", SearchCriteria.Op.EQ, templateId); - } - else if (keyword != null) { - sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - } else if (name != null) { - sc.addAnd("name", SearchCriteria.Op.EQ, name); - } + if (isIso) { + sc.addAnd("format", SearchCriteria.Op.EQ, "ISO"); - if (isIso) { - sc.addAnd("format", SearchCriteria.Op.EQ, "ISO"); + } else { + sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO"); + } - } else { - sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO"); - } + if (!hyperType.equals(HypervisorType.None)) { + sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType); + } - if (!hyperType.equals(HypervisorType.None)) { - sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType); - } + if (bootable != null) { + sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable); + } - if (bootable != null) { - sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable); - } + if (onlyReady) { + sc.addAnd("downloadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); + sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); + } - if (onlyReady){ - sc.addAnd("downloadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); - sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); - } + if (zoneId != null) { + sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); + } - if (zoneId != null){ - sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); - } + if (!showDomr) { + // excluding system template + sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); + } - if (!showDomr){ - // excluding system template - sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); - } + // don't return removed template, this should not be needed since we + // changed annotation for removed field in TemplateJoinVO. + // sc.addAnd("removed", SearchCriteria.Op.NULL); - // don't return removed template, this should not be needed since we changed annotation for removed field in TemplateJoinVO. - //sc.addAnd("removed", SearchCriteria.Op.NULL); + // search unique templates and find details by Ids + Pair, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); + Integer count = uniqueTmplPair.second(); + if (count.intValue() == 0) { + // empty result + return uniqueTmplPair; + } + List uniqueTmpls = uniqueTmplPair.first(); + Long[] vrIds = new Long[uniqueTmpls.size()]; + int i = 0; + for (TemplateJoinVO v : uniqueTmpls) { + vrIds[i++] = v.getId(); + } + List vrs = _templateJoinDao.searchByIds(vrIds); + return new Pair, Integer>(vrs, count); - // search unique templates and find details by Ids - Pair, Integer> uniqueTmplPair = _templateJoinDao.searchAndCount(sc, searchFilter); - Integer count = uniqueTmplPair.second(); - if (count.intValue() == 0) { - // empty result - return uniqueTmplPair; - } - List uniqueTmpls = uniqueTmplPair.first(); - Long[] vrIds = new Long[uniqueTmpls.size()]; - int i = 0; - for (TemplateJoinVO v : uniqueTmpls) { - vrIds[i++] = v.getId(); - } - List vrs = _templateJoinDao.searchByIds(vrIds); - return new Pair, Integer>(vrs, count); - - //TODO: revisit the special logic for iso search in VMTemplateDaoImpl.searchForTemplates and understand why we need to - //specially handle ISO. The original logic is very twisted and no idea about what the code was doing. + // TODO: revisit the special logic for iso search in + // VMTemplateDaoImpl.searchForTemplates and understand why we need to + // specially handle ISO. The original logic is very twisted and no idea + // about what the code was doing. } @@ -2776,7 +2781,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { cmd.getStartIndex(), cmd.getZoneId(), hypervisorType, true, cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags); } - + public ListResponse listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex, Long pageSize) { Pair, Integer> result = listAffinityGroupsInternal(affinityGroupId, diff --git a/server/src/com/cloud/template/TemplateAdapterBase.java b/server/src/com/cloud/template/TemplateAdapterBase.java index aeea8b92b91..fd8b60c99ba 100755 --- a/server/src/com/cloud/template/TemplateAdapterBase.java +++ b/server/src/com/cloud/template/TemplateAdapterBase.java @@ -87,7 +87,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat protected @Inject DataStoreManager storeMgr; @Inject TemplateManager templateMgr; @Inject ConfigurationServer _configServer; - + @Override public boolean stop() { return true; @@ -239,14 +239,9 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId()); _accountMgr.checkAccess(caller, null, true, owner); - HypervisorType hyperType = HypervisorType.None; - if ( cmd.getOsTypeId() != null ){ - hyperType = _osHyperDao.findHypervisorTypeByGuestOsId(cmd.getOsTypeId()); - } - return prepare(true, UserContext.current().getCallerUserId(), cmd.getIsoName(), cmd.getDisplayText(), 64, false, true, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), cmd.isExtractable(), ImageFormat.ISO.toString(), cmd.getOsTypeId(), - cmd.getZoneId(), hyperType, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false); + cmd.getZoneId(), HypervisorType.None, cmd.getChecksum(), cmd.isBootable(), null, owner, null, false); } protected VMTemplateVO persistTemplate(TemplateProfile profile) { From 95e7e270d4b375e4d42e13e951a983c7d22aa3a3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 14:48:34 -0700 Subject: [PATCH 180/303] Fix the hanging issue in deleting ISO referenced by some user vms. --- .../datastore/driver/CloudStackImageStoreDriverImpl.java | 6 ++++++ .../storage/datastore/driver/S3ImageStoreDriverImpl.java | 6 ++++++ .../storage/datastore/driver/SwiftImageStoreDriverImpl.java | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 177d8d8d36e..31fab32eb7a 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -309,6 +309,12 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } } } + } else{ + // cannot delete iso due to some VMs are using this + s_logger.debug("Cannot delete iso since some user vms are referencing it"); + CommandResult result = new CommandResult(); + result.setResult("Cannot delete iso since some user vms are referencing it"); + callback.complete(result); } } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 29cafdbb73c..cbf55b66fc6 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -323,6 +323,12 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } } } + } else{ + // cannot delete iso due to some VMs are using this + s_logger.debug("Cannot delete iso since some user vms are referencing it"); + CommandResult result = new CommandResult(); + result.setResult("Cannot delete iso since some user vms are referencing it"); + callback.complete(result); } } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index db3b225c1ef..003152a309c 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -315,6 +315,12 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } } } + } else{ + // cannot delete iso due to some VMs are using this + s_logger.debug("Cannot delete iso since some user vms are referencing it"); + CommandResult result = new CommandResult(); + result.setResult("Cannot delete iso since some user vms are referencing it"); + callback.complete(result); } } From 252f384e89c85f373d69a9586d451f64217aaac7 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 14:56:26 -0700 Subject: [PATCH 181/303] Fix CLOUDSTACK-2485: ClassCastException in extracting ISO. --- .../cloudstack/storage/image/datastore/ImageStoreEntity.java | 1 + .../cloudstack/storage/image/store/ImageStoreImpl.java | 5 +++-- server/src/com/cloud/storage/upload/UploadMonitorImpl.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java index fb1b1d7df2c..9adcfb131db 100644 --- a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java +++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java @@ -34,4 +34,5 @@ public interface ImageStoreEntity extends DataStore, ImageStore { SnapshotInfo getSnapshot(long snapshotId); boolean exists(DataObject object); Set listTemplates(); + String getMountPoint(); // get the mount point on ssvm. } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 5afe059616f..1b4dddce2e5 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -177,8 +177,9 @@ public class ImageStoreImpl implements ImageStoreEntity { return getDriver().getStoreTO(this); } - public ImageStoreVO getImageStoreVO(){ - return this.imageDataStoreVO; + @Override + public String getMountPoint(){ + return this.imageDataStoreVO.getParent(); } } diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index b944b76e883..b9cee66028f 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -38,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -229,7 +230,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { // Create Symlink at ssvm String path = vmTemplateHost.getInstallPath(); String uuid = UUID.randomUUID().toString() + "." + template.getFormat().getFileExtension(); // adding "." + vhd/ova... etc. - CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreVO)store).getParent(), path, uuid); + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)store).getMountPoint(), path, uuid); Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { errorString = "Unable to create a link for " +type+ " id:"+template.getId() + "," + ans.getDetails(); From 564d3d6fa0fec0ab306c225b9b8fd80771c264c6 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 16:12:49 -0700 Subject: [PATCH 182/303] Fix CLOUDSTACK-2488: Delete iso async job is running forever. --- .../CloudStackImageStoreDriverImpl.java | 5 ++++- .../driver/S3ImageStoreDriverImpl.java | 5 ++++- .../driver/SwiftImageStoreDriverImpl.java | 5 ++++- .../cloud/api/query/dao/UserVmJoinDao.java | 2 ++ .../api/query/dao/UserVmJoinDaoImpl.java | 20 ++++++++++++++++++- 5 files changed, 33 insertions(+), 4 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 31fab32eb7a..6ebdb693209 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -55,6 +55,8 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -100,6 +102,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { private S3Manager _s3Mgr; @Inject AccountDao _accountDao; @Inject UserVmDao _userVmDao; + @Inject UserVmJoinDao _userVmJoinDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject @@ -277,7 +280,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - List userVmUsingIso = _userVmDao.listByIsoId(templateId); + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { // get installpath of this template on image store diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index cbf55b66fc6..9487bbe2832 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -59,6 +59,8 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.S3TO; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -106,6 +108,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { private S3Manager _s3Mgr; @Inject AccountDao _accountDao; @Inject UserVmDao _userVmDao; + @Inject UserVmJoinDao _userVmJoinDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject @@ -289,7 +292,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - List userVmUsingIso = _userVmDao.listByIsoId(templateId); + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { // get installpath of this template on image store diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 003152a309c..69e03495b2b 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -58,6 +58,8 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -105,6 +107,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { private S3Manager _s3Mgr; @Inject AccountDao _accountDao; @Inject UserVmDao _userVmDao; + @Inject UserVmJoinDao _userVmJoinDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject @@ -281,7 +284,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - List userVmUsingIso = _userVmDao.listByIsoId(templateId); + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { // get installpath of this template on image store diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDao.java b/server/src/com/cloud/api/query/dao/UserVmJoinDao.java index 2617a7475ef..bfff83982b4 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDao.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDao.java @@ -36,4 +36,6 @@ public interface UserVmJoinDao extends GenericDao { List newUserVmView(UserVm... userVms); List searchByIds(Long... ids); + + List listActiveByIsoId(Long isoId); } diff --git a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java index 6513ef5dc1d..2d280f19e71 100644 --- a/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java @@ -43,7 +43,9 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.vm.UserVmVO; import com.cloud.vm.VmStats; +import com.cloud.vm.VirtualMachine.State; @Component @@ -55,6 +57,7 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem private ConfigurationDao _configDao; private final SearchBuilder VmDetailSearch; + private final SearchBuilder activeVmByIsoSearch; protected UserVmJoinDaoImpl() { @@ -64,9 +67,24 @@ public class UserVmJoinDaoImpl extends GenericDaoBase implem this._count = "select count(distinct id) from user_vm_view WHERE "; - + activeVmByIsoSearch = createSearchBuilder(); + activeVmByIsoSearch.and("isoId", activeVmByIsoSearch.entity().getIsoId(), SearchCriteria.Op.EQ); + activeVmByIsoSearch.and("stateNotIn", activeVmByIsoSearch.entity().getState(), SearchCriteria.Op.NIN); + activeVmByIsoSearch.done(); } + + @Override + public List listActiveByIsoId(Long isoId) { + SearchCriteria sc = activeVmByIsoSearch.create(); + sc.setParameters("isoId", isoId); + State[] states = new State[2]; + states[0] = State.Error; + states[1] = State.Expunging; + return listBy(sc); + } + + @Override public UserVmResponse newUserVmResponse(String objectName, UserVmJoinVO userVm, EnumSet details, Account caller) { UserVmResponse userVmResponse = new UserVmResponse(); From 68ffe1c70692b04a667e7954cc8b2fd6188403cf Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 14 May 2013 16:20:20 -0700 Subject: [PATCH 183/303] fix bug in create volume from snapshot --- .../storage/resource/StorageProcessor.java | 1 + .../StorageSubsystemCommandHandlerBase.java | 2 + .../motion/AncientDataMotionStrategy.java | 11 +- .../cloudstack/storage/test/SnapshotTest.java | 24 +++- .../storage/volume/VolumeServiceImpl.java | 6 +- .../kvm/storage/KVMStorageProcessor.java | 58 +++++++-- .../resource/VmwareStorageProcessor.java | 118 ++++++++++++++++++ .../resource/XenServerStorageProcessor.java | 68 ++++++++++ 8 files changed, 266 insertions(+), 22 deletions(-) diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/com/cloud/storage/resource/StorageProcessor.java index ec965ed424b..86bfe4b92b9 100644 --- a/core/src/com/cloud/storage/resource/StorageProcessor.java +++ b/core/src/com/cloud/storage/resource/StorageProcessor.java @@ -42,4 +42,5 @@ public interface StorageProcessor { public Answer createVolume(CreateObjectCommand cmd); public Answer createSnapshot(CreateObjectCommand cmd); public Answer deleteVolume(DeleteCommand cmd); + public Answer createVolumeFromSnapshot(CopyCommand cmd); } diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java index 8f76e93d180..d167d61867b 100644 --- a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java @@ -82,6 +82,8 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma } } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && srcData.getDataStore().getRole() == DataStoreRole.Primary) { return processor.backupSnasphot(cmd); + } else if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.VOLUME) { + return processor.createVolumeFromSnapshot(cmd); } return new Answer(cmd, false, "not implemented yet"); 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 index 4bd290b7011..73be1625336 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -231,12 +231,11 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { .getDefaultValue())); CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait); - - - Answer answer = storageMgr - .sendToPool(pool, cmd); + EndPoint ep = selector.select(snapObj, volObj); + Answer answer = ep.sendMessage(cmd); + return answer; - } catch (StorageUnavailableException e) { + } catch (Exception e) { s_logger.error(basicErrMsg, e); throw new CloudRuntimeException(basicErrMsg); } finally { @@ -300,7 +299,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) { answer = copySnapshot(srcData, destData); - } + } if (answer != null && !answer.getResult()) { errMsg = answer.getDetails(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index d667a787353..264db68eefb 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -360,7 +360,7 @@ public class SnapshotTest extends CloudStackTestNGBase { return null; } - @Test + //@Test public void createSnapshot() { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); @@ -394,7 +394,7 @@ public class SnapshotTest extends CloudStackTestNGBase { return image; } - @Test + //@Test public void createTemplateFromSnapshot() { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); @@ -416,4 +416,24 @@ public class SnapshotTest extends CloudStackTestNGBase { DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); } + + @Test + public void createVolumeFromSnapshot() { + VolumeInfo vol = createCopyBaseImage(); + SnapshotVO snapshotVO = createSnapshotInDb(vol); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + boolean result = false; + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + snapshot = strategy.takeSnapshot(snapshot); + result = true; + } + } + + AssertJUnit.assertTrue(result); + + VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId()); + VolumeInfo newVol = this.volFactory.getVolume(volVO.getId()); + this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 414f802bc2d..bd6df5798c6 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -539,7 +539,11 @@ public class VolumeServiceImpl implements VolumeService { } try { - volume.processEvent(event); + if (result.isSuccess()) { + volume.processEvent(event, result.getAnswer()); + } else { + volume.processEvent(event); + } snapshot.processEvent(event); } catch (Exception e) { s_logger.debug("create volume from snapshot failed", e); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 3bdf4287db0..c3fa12bbf3e 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -20,7 +20,6 @@ package com.cloud.hypervisor.kvm.storage; import java.io.File; import java.io.FileOutputStream; -import java.io.IOException; import java.net.URISyntaxException; import java.text.DateFormat; import java.text.MessageFormat; @@ -47,9 +46,9 @@ import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.qemu.QemuImg; +import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.cloudstack.utils.qemu.QemuImgException; import org.apache.cloudstack.utils.qemu.QemuImgFile; -import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat; import org.apache.log4j.Logger; import org.libvirt.Connect; import org.libvirt.Domain; @@ -58,37 +57,28 @@ import org.libvirt.DomainSnapshot; import org.libvirt.LibvirtException; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.AttachVolumeAnswer; -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.agent.api.ManageSnapshotAnswer; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NfsTO; -import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.agent.api.to.VolumeTO; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource; import com.cloud.hypervisor.kvm.resource.LibvirtConnection; import com.cloud.hypervisor.kvm.resource.LibvirtDomainXMLParser; import com.cloud.hypervisor.kvm.resource.LibvirtVMDef.DiskDef; import com.cloud.storage.JavaStorageLayer; -import com.cloud.storage.StorageLayer; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; +import com.cloud.storage.StorageLayer; import com.cloud.storage.resource.StorageProcessor; import com.cloud.storage.template.Processor; +import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.storage.template.QCOW2Processor; import com.cloud.storage.template.TemplateLocation; -import com.cloud.storage.template.Processor.FormatInfo; import com.cloud.utils.NumbersUtil; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; -import com.cloud.vm.DiskProfile; public class KVMStorageProcessor implements StorageProcessor { private static final Logger s_logger = Logger.getLogger(KVMStorageProcessor.class); @@ -870,4 +860,46 @@ public class KVMStorageProcessor implements StorageProcessor { } } + @Override + public Answer createVolumeFromSnapshot(CopyCommand cmd) { + try { + DataTO srcData = cmd.getSrcTO(); + SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; + DataTO destData = cmd.getDestTO(); + PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); + DataStoreTO imageStore = srcData.getDataStore(); + + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + + NfsTO nfsImageStore = (NfsTO)imageStore; + + String snapshotPath = snapshot.getPath(); + int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + String snapshotName = snapshotPath.substring(index + 1); + KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI( + nfsImageStore.getUrl() + File.separator + snapshotPath); + KVMPhysicalDisk snapshotDisk = secondaryPool.getPhysicalDisk(snapshotName); + + String primaryUuid = pool.getUuid(); + KVMStoragePool primaryPool = storagePoolMgr + .getStoragePool(pool.getPoolType(), + primaryUuid); + String volUuid = UUID.randomUUID().toString(); + KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, + volUuid, primaryPool); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(disk.getName()); + newVol.setSize(disk.getVirtualSize()); + return new CopyCmdAnswer( + newVol); + } catch (CloudRuntimeException e) { + return new CopyCmdAnswer(e.toString() + ); + } + } + } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 240c62f5a4a..16bfaf536b3 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -44,6 +44,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.BackupSnapshotAnswer; import com.cloud.agent.api.Command; +import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotAnswer; import com.cloud.agent.api.ManageSnapshotCommand; import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; @@ -980,6 +981,7 @@ public class VmwareStorageProcessor implements StorageProcessor { VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(volumeUuid); + newVol.setSize(volume.getSize() / (1024L * 1024L)); return new CreateObjectAnswer(newVol); } finally { s_logger.info("Destroy dummy VM after volume creation"); @@ -1154,4 +1156,120 @@ public class VmwareStorageProcessor implements StorageProcessor { return new Answer(cmd, false, msg); } } + + private Long restoreVolumeFromSecStorage(VmwareHypervisorHost hyperHost, DatastoreMO primaryDsMo, String newVolumeName, + String secStorageUrl, String secStorageDir, String backupName) throws Exception { + + String secondaryMountPoint = mountService.getMountPoint(secStorageUrl); + String srcOVAFileName = secondaryMountPoint + "/" + secStorageDir + "/" + + backupName + "." + ImageFormat.OVA.getFileExtension(); + String snapshotDir = ""; + if (backupName.contains("/")){ + snapshotDir = backupName.split("/")[0]; + } + + File ovafile = new File(srcOVAFileName); + String srcOVFFileName = secondaryMountPoint + "/" + secStorageDir + "/" + + backupName + ".ovf"; + File ovfFile = new File(srcOVFFileName); + // String srcFileName = getOVFFilePath(srcOVAFileName); + if (!ovfFile.exists()) { + srcOVFFileName = getOVFFilePath(srcOVAFileName); + if(srcOVFFileName == null && ovafile.exists() ) { // volss: ova file exists; o/w can't do tar + Script command = new Script("tar", 0, s_logger); + command.add("--no-same-owner"); + command.add("-xf", srcOVAFileName); + command.setWorkDir(secondaryMountPoint + "/" + secStorageDir + "/" + snapshotDir); + s_logger.info("Executing command: " + command.toString()); + String result = command.execute(); + if(result != null) { + String msg = "Unable to unpack snapshot OVA file at: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); + } + } else { + String msg = "Unable to find snapshot OVA file at: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); + } + + srcOVFFileName = getOVFFilePath(srcOVAFileName); + } + if(srcOVFFileName == null) { + String msg = "Unable to locate OVF file in template package directory: " + srcOVAFileName; + s_logger.error(msg); + throw new Exception(msg); + } + + VirtualMachineMO clonedVm = null; + try { + hyperHost.importVmFromOVF(srcOVFFileName, newVolumeName, primaryDsMo, "thin"); + clonedVm = hyperHost.findVmOnHyperHost(newVolumeName); + if(clonedVm == null) + throw new Exception("Unable to create container VM for volume creation"); + + clonedVm.moveAllVmDiskFiles(primaryDsMo, "", false); + clonedVm.detachAllDisks(); + return _storage.getSize(srcOVFFileName); + } finally { + if(clonedVm != null) { + clonedVm.detachAllDisks(); + clonedVm.destroy(); + } + } + } + + @Override + public Answer createVolumeFromSnapshot(CopyCommand cmd) { + DataTO srcData = cmd.getSrcTO(); + SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; + DataTO destData = cmd.getDestTO(); + PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); + DataStoreTO imageStore = srcData.getDataStore(); + + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + + NfsTO nfsImageStore = (NfsTO)imageStore; + String primaryStorageNameLabel = pool.getUuid(); + + String secondaryStorageUrl = nfsImageStore.getUrl(); + String backedUpSnapshotUuid = snapshot.getPath(); + int index = backedUpSnapshotUuid.lastIndexOf(File.separator); + String backupPath = backedUpSnapshotUuid.substring(0, index); + backedUpSnapshotUuid = backedUpSnapshotUuid.substring(index + 1); + String details = null; + String newVolumeName = UUID.randomUUID().toString().replaceAll("-", ""); + + VmwareContext context = hostService.getServiceContext(cmd); + try { + VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); + ManagedObjectReference morPrimaryDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, + primaryStorageNameLabel); + if (morPrimaryDs == null) { + String msg = "Unable to find datastore: " + primaryStorageNameLabel; + s_logger.error(msg); + throw new Exception(msg); + } + + DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs); + Long size = restoreVolumeFromSecStorage(hyperHost, primaryDsMo, + newVolumeName, secondaryStorageUrl, backupPath, backedUpSnapshotUuid); + + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(newVolumeName); + newVol.setSize(size); + return new CopyCmdAnswer(newVol); + } catch (Throwable e) { + if (e instanceof RemoteException) { + hostService.invalidateServiceContext(context); + } + + s_logger.error("Unexpecpted exception ", e); + details = "CreateVolumeFromSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); + } + return new CopyCmdAnswer(details); + } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 03a2c28985d..0ef35195a00 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -55,6 +55,7 @@ import org.apache.xmlrpc.XmlRpcException; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CreateStoragePoolCommand; +import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; @@ -1402,4 +1403,71 @@ public class XenServerStorageProcessor implements StorageProcessor { } return new CopyCmdAnswer(details); } + + @Override + public Answer createVolumeFromSnapshot(CopyCommand cmd) { + Connection conn = this.hypervisorResource.getConnection(); + DataTO srcData = cmd.getSrcTO(); + SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; + DataTO destData = cmd.getDestTO(); + PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); + DataStoreTO imageStore = srcData.getDataStore(); + + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } + + NfsTO nfsImageStore = (NfsTO)imageStore; + String primaryStorageNameLabel = pool.getUuid(); + String secondaryStorageUrl = nfsImageStore.getUrl(); + int wait = cmd.getWait(); + boolean result = false; + // Generic error message. + String details = null; + String volumeUUID = null; + + if (secondaryStorageUrl == null) { + details += " because the URL passed: " + secondaryStorageUrl + " is invalid."; + return new CopyCmdAnswer(details); + } + try { + SR primaryStorageSR = this.hypervisorResource.getSRByNameLabelandHost(conn, primaryStorageNameLabel); + if (primaryStorageSR == null) { + throw new InternalErrorException("Could not create volume from snapshot because the primary Storage SR could not be created from the name label: " + + primaryStorageNameLabel); + } + // Get the absolute path of the snapshot on the secondary storage. + String snapshotInstallPath = snapshot.getPath(); + int index = snapshotInstallPath.lastIndexOf(File.separator); + String snapshotName = snapshotInstallPath.substring(index + 1); + + if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) { + snapshotInstallPath = snapshotInstallPath + ".vhd"; + } + URI snapshotURI = new URI(secondaryStorageUrl + File.separator + snapshotInstallPath); + String snapshotPath = snapshotURI.getHost() + ":" + snapshotURI.getPath(); + String srUuid = primaryStorageSR.getUuid(conn); + volumeUUID = copy_vhd_from_secondarystorage(conn, snapshotPath, srUuid, wait); + result = true; + VDI volume = VDI.getByUuid(conn, volumeUUID); + VDI.Record vdir = volume.getRecord(conn); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(volumeUUID); + newVol.setSize(vdir.virtualSize); + return new CopyCmdAnswer(newVol); + } catch (XenAPIException e) { + details += " due to " + e.toString(); + s_logger.warn(details, e); + } catch (Exception e) { + details += " due to " + e.getMessage(); + s_logger.warn(details, e); + } + if (!result) { + // Is this logged at a higher level? + s_logger.error(details); + } + + // In all cases return something. + return new CopyCmdAnswer(details); + } } From c6a5a7ee006891b425d1ef3d7be187754930e094 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 14 May 2013 21:52:29 -0700 Subject: [PATCH 184/303] Fix CLOUDSTACK-2495: public templates are not visible to non-root users. --- .../com/cloud/api/query/QueryManagerImpl.java | 262 +++++++++--------- 1 file changed, 130 insertions(+), 132 deletions(-) diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index f7fea53f55d..c2e9a008db5 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -2525,7 +2525,12 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags) { VMTemplateVO template = null; - // verify templateId parameter + Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); + isAscending = (isAscending == null ? true : isAscending); + Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize); + SearchCriteria sc = _templateJoinDao.createSearchCriteria(); + + // verify templateId parameter and specially handle it if (templateId != null) { template = _templateDao.findById(templateId); if (template == null) { @@ -2550,167 +2555,160 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { Account owner = _accountMgr.getAccount(template.getAccountId()); _accountMgr.checkAccess(caller, null, true, owner); } - } - DomainVO domain = null; - if (!permittedAccounts.isEmpty()) { - domain = _domainDao.findById(permittedAccounts.get(0).getDomainId()); + // if templateId is specified, then we will just use the id to + // search and ignore other query parameters + sc.addAnd("id", SearchCriteria.Op.EQ, templateId); } else { - domain = _domainDao.findById(DomainVO.ROOT_DOMAIN); - } - List hypers = null; - if (!isIso) { - hypers = _resourceMgr.listAvailHypervisorInZone(null, null); - } + DomainVO domain = null; + if (!permittedAccounts.isEmpty()) { + domain = _domainDao.findById(permittedAccounts.get(0).getDomainId()); + } else { + domain = _domainDao.findById(DomainVO.ROOT_DOMAIN); + } - Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); - isAscending = (isAscending == null ? true : isAscending); - Filter searchFilter = new Filter(TemplateJoinVO.class, "sortKey", isAscending, startIndex, pageSize); - SearchCriteria sc = _templateJoinDao.createSearchCriteria(); + List hypers = null; + if (!isIso) { + hypers = _resourceMgr.listAvailHypervisorInZone(null, null); + } - // add criteria for project or not - if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { - sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); - } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { - sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); - } + // add criteria for project or not + if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { + sc.addAnd("accountType", SearchCriteria.Op.NEQ, Account.ACCOUNT_TYPE_PROJECT); + } else if (listProjectResourcesCriteria == ListProjectResourcesCriteria.ListProjectResourcesOnly) { + sc.addAnd("accountType", SearchCriteria.Op.EQ, Account.ACCOUNT_TYPE_PROJECT); + } - // add criteria for domain path in case of domain admin - if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) - && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { - sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); - } + // add criteria for domain path in case of domain admin + if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) + && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + sc.addAnd("domainPath", SearchCriteria.Op.LIKE, domain.getPath() + "%"); + } - List relatedDomainIds = new ArrayList(); - List permittedAccountIds = new ArrayList(); - if (!permittedAccounts.isEmpty()) { - for (Account account : permittedAccounts) { - permittedAccountIds.add(account.getId()); - DomainVO accountDomain = _domainDao.findById(account.getDomainId()); + List relatedDomainIds = new ArrayList(); + List permittedAccountIds = new ArrayList(); + if (!permittedAccounts.isEmpty()) { + for (Account account : permittedAccounts) { + permittedAccountIds.add(account.getId()); + DomainVO accountDomain = _domainDao.findById(account.getDomainId()); - // get all parent domain ID's all the way till root domain - DomainVO domainTreeNode = accountDomain; - relatedDomainIds.add(domainTreeNode.getId()); - while (domainTreeNode.getParent() != null) { - domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); + // get all parent domain ID's all the way till root domain + DomainVO domainTreeNode = accountDomain; relatedDomainIds.add(domainTreeNode.getId()); - } + while (domainTreeNode.getParent() != null) { + domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); + relatedDomainIds.add(domainTreeNode.getId()); + } - // get all child domain ID's - if (_accountMgr.isAdmin(account.getType())) { - List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); - for (DomainVO childDomain : allChildDomains) { - relatedDomainIds.add(childDomain.getId()); + // get all child domain ID's + if (_accountMgr.isAdmin(account.getType())) { + List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); + for (DomainVO childDomain : allChildDomains) { + relatedDomainIds.add(childDomain.getId()); + } } } } - } - if (!isIso) { - // add hypervisor criteria for template case - if (hypers != null && !hypers.isEmpty()) { - String[] relatedHypers = new String[hypers.size()]; - for (int i = 0; i < hypers.size(); i++) { - relatedHypers[i] = hypers.get(i).toString(); + if (!isIso) { + // add hypervisor criteria for template case + if (hypers != null && !hypers.isEmpty()) { + String[] relatedHypers = new String[hypers.size()]; + for (int i = 0; i < hypers.size(); i++) { + relatedHypers[i] = hypers.get(i).toString(); + } + sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers); } - sc.addAnd("hypervisorType", SearchCriteria.Op.IN, relatedHypers); } - } - // control different template filters - if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { - sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); - if (templateFilter == TemplateFilter.featured) { - sc.addAnd("featured", SearchCriteria.Op.EQ, true); - } else { - sc.addAnd("featured", SearchCriteria.Op.EQ, false); - } - if (!permittedAccounts.isEmpty()) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); - scc.addOr("domainId", SearchCriteria.Op.NULL); - sc.addAnd("domainId", SearchCriteria.Op.SC, scc); - - if (!_accountMgr.isAdmin(caller.getType())) { - // for non-root users, we should only show featured and - // community templates that they can see + // control different template filters + if (templateFilter == TemplateFilter.featured || templateFilter == TemplateFilter.community) { + sc.addAnd("publicTemplate", SearchCriteria.Op.EQ, true); + if (templateFilter == TemplateFilter.featured) { + sc.addAnd("featured", SearchCriteria.Op.EQ, true); + } else { + sc.addAnd("featured", SearchCriteria.Op.EQ, false); + } + if (!permittedAccounts.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("domainId", SearchCriteria.Op.IN, relatedDomainIds.toArray()); + scc.addOr("domainId", SearchCriteria.Op.NULL); + sc.addAnd("domainId", SearchCriteria.Op.SC, scc); + } + } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { + if (!permittedAccounts.isEmpty()) { sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); } - } - } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { - if (!permittedAccounts.isEmpty()) { - sc.addAnd("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - } - } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - sc.addAnd("accountId", SearchCriteria.Op.SC, scc); - } else if (templateFilter == TemplateFilter.executable) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); - if (!permittedAccounts.isEmpty()) { + } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); - } - sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); - } - - // add tags criteria - if (tags != null && !tags.isEmpty()) { - SearchCriteria scc = _templateJoinDao.createSearchCriteria(); - int count = 0; - for (String key : tags.keySet()) { - SearchCriteria scTag = _templateJoinDao.createSearchCriteria(); - scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); - scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); - if (isIso) { - scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.ISO); - } else { - scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.Template); + scc.addOr("sharedAccountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); + sc.addAnd("accountId", SearchCriteria.Op.SC, scc); + } else if (templateFilter == TemplateFilter.executable) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + scc.addOr("publicTemplate", SearchCriteria.Op.EQ, true); + if (!permittedAccounts.isEmpty()) { + scc.addOr("accountId", SearchCriteria.Op.IN, permittedAccountIds.toArray()); } - scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); - count++; + sc.addAnd("publicTemplate", SearchCriteria.Op.SC, scc); } - sc.addAnd("tagKey", SearchCriteria.Op.SC, scc); - } - // other criteria - if (templateId != null) { - sc.addAnd("id", SearchCriteria.Op.EQ, templateId); - } else if (keyword != null) { - sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); - } else if (name != null) { - sc.addAnd("name", SearchCriteria.Op.EQ, name); - } + // add tags criteria + if (tags != null && !tags.isEmpty()) { + SearchCriteria scc = _templateJoinDao.createSearchCriteria(); + int count = 0; + for (String key : tags.keySet()) { + SearchCriteria scTag = _templateJoinDao.createSearchCriteria(); + scTag.addAnd("tagKey", SearchCriteria.Op.EQ, key); + scTag.addAnd("tagValue", SearchCriteria.Op.EQ, tags.get(key)); + if (isIso) { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.ISO); + } else { + scTag.addAnd("tagResourceType", SearchCriteria.Op.EQ, TaggedResourceType.Template); + } + scc.addOr("tagKey", SearchCriteria.Op.SC, scTag); + count++; + } + sc.addAnd("tagKey", SearchCriteria.Op.SC, scc); + } - if (isIso) { - sc.addAnd("format", SearchCriteria.Op.EQ, "ISO"); + // other criteria - } else { - sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO"); - } + if (keyword != null) { + sc.addAnd("name", SearchCriteria.Op.LIKE, "%" + keyword + "%"); + } else if (name != null) { + sc.addAnd("name", SearchCriteria.Op.EQ, name); + } - if (!hyperType.equals(HypervisorType.None)) { - sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType); - } + if (isIso) { + sc.addAnd("format", SearchCriteria.Op.EQ, "ISO"); - if (bootable != null) { - sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable); - } + } else { + sc.addAnd("format", SearchCriteria.Op.NEQ, "ISO"); + } - if (onlyReady) { - sc.addAnd("downloadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); - sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); - } + if (!hyperType.equals(HypervisorType.None)) { + sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hyperType); + } - if (zoneId != null) { - sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); - } + if (bootable != null) { + sc.addAnd("bootable", SearchCriteria.Op.EQ, bootable); + } - if (!showDomr) { - // excluding system template - sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); + if (onlyReady) { + sc.addAnd("downloadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); + sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); + } + + if (zoneId != null) { + sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); + } + + if (!showDomr) { + // excluding system template + sc.addAnd("templateType", SearchCriteria.Op.NEQ, Storage.TemplateType.SYSTEM); + } } // don't return removed template, this should not be needed since we From 879a954b98bc071054770fd8625c4f4cc3e0c10c Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 14 May 2013 21:57:07 -0700 Subject: [PATCH 185/303] delete snapshot at the backend --- .../com/cloud/agent/api/SnapshotCommand.java | 4 +- .../storage/resource/StorageProcessor.java | 3 +- .../StorageSubsystemCommandHandlerBase.java | 2 + .../MockLocalNfsSecondaryStorageResource.java | 3 + .../storage/test/MockLocalHostEndPoint.java | 20 ++++ .../cloudstack/storage/test/SnapshotTest.java | 95 +++++++++++++------ .../storage/snapshot/SnapshotServiceImpl.java | 37 +++++++- .../snapshot/XenserverSnapshotStrategy.java | 5 +- .../cloudstack/storage/LocalHostEndpoint.java | 2 +- .../kvm/storage/KVMStorageProcessor.java | 6 ++ .../resource/VmwareStorageProcessor.java | 13 +++ .../resource/XenServerStorageProcessor.java | 30 ++++++ .../CloudStackImageStoreDriverImpl.java | 86 +++++++---------- .../cloud/template/TemplateManagerImpl.java | 9 ++ .../resource/NfsSecondaryStorageResource.java | 22 +++-- 15 files changed, 242 insertions(+), 95 deletions(-) create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java diff --git a/core/src/com/cloud/agent/api/SnapshotCommand.java b/core/src/com/cloud/agent/api/SnapshotCommand.java index d8abeb62371..ccf9613d5e8 100644 --- a/core/src/com/cloud/agent/api/SnapshotCommand.java +++ b/core/src/com/cloud/agent/api/SnapshotCommand.java @@ -53,8 +53,8 @@ public class SnapshotCommand extends Command { public SnapshotCommand(StoragePool pool, String secondaryStorageUrl, String snapshotUuid, String snapshotName, Long dcId, Long accountId, Long volumeId) { - this.primaryStoragePoolNameLabel = pool.getUuid(); - this.primaryPool = new StorageFilerTO(pool); + // this.primaryStoragePoolNameLabel = pool.getUuid(); + //this.primaryPool = new StorageFilerTO(pool); this.snapshotUuid = snapshotUuid; this.secondaryStorageUrl = secondaryStorageUrl; this.dcId = dcId; diff --git a/core/src/com/cloud/storage/resource/StorageProcessor.java b/core/src/com/cloud/storage/resource/StorageProcessor.java index 86bfe4b92b9..ca441edcb79 100644 --- a/core/src/com/cloud/storage/resource/StorageProcessor.java +++ b/core/src/com/cloud/storage/resource/StorageProcessor.java @@ -25,8 +25,6 @@ import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DettachCommand; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.to.DataTO; -import com.cloud.agent.api.to.DiskTO; public interface StorageProcessor { public Answer copyTemplateToPrimaryStorage(CopyCommand cmd); @@ -43,4 +41,5 @@ public interface StorageProcessor { public Answer createSnapshot(CreateObjectCommand cmd); public Answer deleteVolume(DeleteCommand cmd); public Answer createVolumeFromSnapshot(CopyCommand cmd); + public Answer deleteSnapshot(DeleteCommand cmd); } diff --git a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java index d167d61867b..23ccd318253 100644 --- a/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java +++ b/core/src/com/cloud/storage/resource/StorageSubsystemCommandHandlerBase.java @@ -110,6 +110,8 @@ public class StorageSubsystemCommandHandlerBase implements StorageSubsystemComma Answer answer = null; if (data.getObjectType() == DataObjectType.VOLUME) { answer = processor.deleteVolume(cmd); + } else if (data.getObjectType() == DataObjectType.SNAPSHOT) { + answer = processor.deleteSnapshot(cmd); } else { answer = new Answer(cmd, false, "unsupported type"); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index 6087bd21fc7..61c09dbfa30 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -51,6 +51,7 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.S3Utils; import com.cloud.utils.UriUtils; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; @Component public class MockLocalNfsSecondaryStorageResource extends @@ -67,6 +68,8 @@ public class MockLocalNfsSecondaryStorageResource extends // TODO Auto-generated catch block e.printStackTrace(); } + + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh"); /* _storage = new JavaStorageLayer(); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java new file mode 100644 index 00000000000..31901e24d6b --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java @@ -0,0 +1,20 @@ +package org.apache.cloudstack.storage.test; + +import org.apache.cloudstack.storage.LocalHostEndpoint; +import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.DownloadCommand; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.DeleteSnapshotBackupCommand; + +public class MockLocalHostEndPoint extends LocalHostEndpoint { + @Override + public Answer sendMessage(Command cmd) { + if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand) || (cmd instanceof DeleteSnapshotBackupCommand)) { + return resource.executeRequest(cmd); + } + // TODO Auto-generated method stub + return new Answer(cmd, false, "unsupported command:" + cmd.toString()); + } +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 264db68eefb..2739b45eabd 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -156,6 +156,7 @@ public class SnapshotTest extends CloudStackTestNGBase { long primaryStoreId; VMTemplateVO image; String imageStoreName = "testImageStore"; + RemoteHostEndPoint remoteEp; @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -250,6 +251,7 @@ public class SnapshotTest extends CloudStackTestNGBase { TemplateObjectTO to = new TemplateObjectTO(); to.setPath(this.getImageInstallPath()); to.setFormat(ImageFormat.VHD); + to.setSize(1000L); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); @@ -263,10 +265,10 @@ public class SnapshotTest extends CloudStackTestNGBase { hosts.add(this.host); Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); - RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(remoteEp); + Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(remoteEp); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp); Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId()); } @@ -360,20 +362,35 @@ public class SnapshotTest extends CloudStackTestNGBase { return null; } - //@Test + @Test public void createSnapshot() { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + SnapshotInfo newSnapshot = null; for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { - strategy.takeSnapshot(snapshot); + newSnapshot = strategy.takeSnapshot(snapshot); } } + AssertJUnit.assertNotNull(newSnapshot); + + LocalHostEndpoint ep = new MockLocalHostEndPoint(); + ep.setResource(new MockLocalNfsSecondaryStorageResource()); + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + + //delete snapshot + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + strategy.deleteSnapshot(newSnapshot.getId()); + } + } + + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp); } private VMTemplateVO createTemplateInDb() { - image = new VMTemplateVO(); + VMTemplateVO image = new VMTemplateVO(); image.setTemplateType(TemplateType.USER); image.setUniqueName(UUID.randomUUID().toString()); @@ -393,8 +410,50 @@ public class SnapshotTest extends CloudStackTestNGBase { image = imageDataDao.persist(image); return image; } + + @Test + public void createVolumeFromSnapshot() { + VolumeInfo vol = createCopyBaseImage(); + SnapshotVO snapshotVO = createSnapshotInDb(vol); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + boolean result = false; + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + snapshot = strategy.takeSnapshot(snapshot); + result = true; + } + } - //@Test + AssertJUnit.assertTrue(result); + + VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId()); + VolumeInfo newVol = this.volFactory.getVolume(volVO.getId()); + this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); + } + + @Test + public void deleteSnapshot() { + VolumeInfo vol = createCopyBaseImage(); + SnapshotVO snapshotVO = createSnapshotInDb(vol); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + SnapshotInfo newSnapshot = null; + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + newSnapshot = strategy.takeSnapshot(snapshot); + } + } + AssertJUnit.assertNotNull(newSnapshot); + + //create another snapshot + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + strategy.deleteSnapshot(newSnapshot.getId()); + } + } + + } + + @Test public void createTemplateFromSnapshot() { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); @@ -417,23 +476,5 @@ public class SnapshotTest extends CloudStackTestNGBase { this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); } - @Test - public void createVolumeFromSnapshot() { - VolumeInfo vol = createCopyBaseImage(); - SnapshotVO snapshotVO = createSnapshotInDb(vol); - SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); - boolean result = false; - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot)) { - snapshot = strategy.takeSnapshot(snapshot); - result = true; - } - } - - AssertJUnit.assertTrue(result); - - VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId()); - VolumeInfo newVol = this.volFactory.getVolume(volVO.getId()); - this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); - } + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 12d80576c85..fa6d558f532 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -299,6 +299,9 @@ public class SnapshotServiceImpl implements SnapshotService { try { SnapshotResult res = future.get(); + if (res.isFailed()) { + throw new CloudRuntimeException(res.getResult()); + } SnapshotInfo destSnapshot = res.getSnashot(); return destSnapshot; } catch (InterruptedException e) { @@ -319,6 +322,12 @@ public class SnapshotServiceImpl implements SnapshotService { AsyncCallFuture future = context.future; SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer()); if (result.isFailed()) { + try { + destSnapshot.processEvent(Event.OperationFailed); + srcSnapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e) { + s_logger.debug("Failed to update state: " + e.toString()); + } snapResult.setResult(result.getResult()); future.complete(snapResult); return null; @@ -397,7 +406,33 @@ public class SnapshotServiceImpl implements SnapshotService { @Override public boolean deleteSnapshot(SnapshotInfo snapInfo) { - return true; + snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + + AsyncCallFuture future = new AsyncCallFuture(); + DeleteSnapshotContext context = new DeleteSnapshotContext(null, + snapInfo, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setCallback( + caller.getTarget().deleteSnapshotCallback(null, null)) + .setContext(context); + DataStore store = snapInfo.getDataStore(); + store.getDriver().deleteAsync(snapInfo, caller); + + SnapshotResult result = null; + try { + result = future.get(); + if (result.isFailed()) { + throw new CloudRuntimeException(result.getResult()); + } + return true; + } catch (InterruptedException e) { + s_logger.debug("delete snapshot is failed: " + e.toString()); + } catch (ExecutionException e) { + s_logger.debug("delete snapshot is failed: " + e.toString()); + } + + return false; } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 072d14bf07a..32504eeaed5 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -139,7 +139,7 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { SnapshotInfo child = snapshot.getChild(); SnapshotInfo parent = snapshot.getParent(); if (child == null) { - if (!parent.getPath().equalsIgnoreCase(snapshot.getPath())) { + if (parent == null || !parent.getPath().equalsIgnoreCase(snapshot.getPath())) { this.snapshotSvr.deleteSnapshot(snapshot); snapshot = parent; continue; @@ -178,9 +178,10 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { } try { + /* if (snapshotOnPrimary != null) { deleteSnapshotChain(snapshotOnPrimary); - } + }*/ SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image); if (snapshotOnImage != null) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 525a507a30b..3267de8eef8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -36,7 +36,7 @@ import com.cloud.storage.download.DownloadListener; public class LocalHostEndpoint implements EndPoint { private ScheduledExecutorService executor; - ServerResource resource; + protected ServerResource resource; public LocalHostEndpoint() { resource = new LocalNfsSecondaryStorageResource(); executor = Executors.newScheduledThreadPool(10); diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index c3fa12bbf3e..53a9308a3ac 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -409,6 +409,8 @@ public class KVMStorageProcessor implements StorageProcessor { TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(templateFolder + File.separator + templateName + ".qcow2"); + newTemplate.setSize(info.virtualSize); + newTemplate.setFormat(ImageFormat.QCOW2); return new CopyCmdAnswer(newTemplate); } catch (Exception e) { s_logger.debug("Failed to create template from volume: " + e.toString()); @@ -902,4 +904,8 @@ public class KVMStorageProcessor implements StorageProcessor { } } + @Override + public Answer deleteSnapshot(DeleteCommand cmd) { + return new Answer(cmd); + } } diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java index 16bfaf536b3..d3df0f59ce9 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java @@ -69,6 +69,7 @@ import com.cloud.hypervisor.vmware.resource.VmwareResource; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.serializer.GsonHelper; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.StorageLayer; import com.cloud.storage.Volume; @@ -579,6 +580,7 @@ public class VmwareStorageProcessor implements StorageProcessor { TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(template.getName()); newTemplate.setFormat(ImageFormat.OVA); + newTemplate.setSize(result.third()); return new CopyCmdAnswer(newTemplate); } catch (Throwable e) { @@ -1272,4 +1274,15 @@ public class VmwareStorageProcessor implements StorageProcessor { } return new CopyCmdAnswer(details); } + + @Override + public Answer deleteSnapshot(DeleteCommand cmd) { + SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getData(); + DataStoreTO store = snapshot.getDataStore(); + if (store.getRole() == DataStoreRole.Primary) { + return new Answer(cmd); + } else { + return new Answer(cmd, false, "unsupported command"); + } + } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 0ef35195a00..bdc3d30542f 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -66,6 +66,7 @@ import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.exception.InternalErrorException; import com.cloud.hypervisor.xen.resource.CitrixResourceBase.SRType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.resource.StorageProcessor; @@ -1389,6 +1390,7 @@ public class XenServerStorageProcessor implements StorageProcessor { TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(installPath); newTemplate.setFormat(ImageFormat.VHD); + newTemplate.setSize(virtualSize); CopyCmdAnswer answer = new CopyCmdAnswer(newTemplate); return answer; } catch (Exception e) { @@ -1470,4 +1472,32 @@ public class XenServerStorageProcessor implements StorageProcessor { // In all cases return something. return new CopyCmdAnswer(details); } + + @Override + public Answer deleteSnapshot(DeleteCommand cmd) { + SnapshotObjectTO snapshot = (SnapshotObjectTO)cmd.getData(); + DataStoreTO store = snapshot.getDataStore(); + if (store.getRole() == DataStoreRole.Primary) { + Connection conn = this.hypervisorResource.getConnection(); + VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath()); + if (snapshotVdi == null) { + return new Answer(null); + } + String errMsg = null; + try { + this.deleteVDI(conn, snapshotVdi); + } catch (BadServerResponse e) { + s_logger.debug("delete snapshot failed:" + e.toString()); + errMsg = e.toString(); + } catch (XenAPIException e) { + s_logger.debug("delete snapshot failed:" + e.toString()); + errMsg = e.toString(); + } catch (XmlRpcException e) { + s_logger.debug("delete snapshot failed:" + e.toString()); + errMsg = e.toString(); + } + return new Answer(cmd, false, errMsg); + } + return new Answer(cmd, false, "unsupported storage type"); + } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 6ebdb693209..0c46d5e2ea7 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -48,6 +48,7 @@ import org.apache.cloudstack.storage.snapshot.SnapshotObject; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; @@ -101,8 +102,6 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { @Inject private S3Manager _s3Mgr; @Inject AccountDao _accountDao; - @Inject UserVmDao _userVmDao; - @Inject UserVmJoinDao _userVmJoinDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject @@ -280,46 +279,37 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); - // check if there is any VM using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - result.setSuccess(false); - result.setResult("Delete template failed"); - callback.complete(result); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSuccess(false); + result.setResult("Delete template failed"); + callback.complete(result); - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - result.setSuccess(true); - callback.complete(result); - } + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSuccess(true); + callback.complete(result); + } - List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } - } - } - } else{ - // cannot delete iso due to some VMs are using this - s_logger.debug("Cannot delete iso since some user vms are referencing it"); - CommandResult result = new CommandResult(); - result.setResult("Cannot delete iso since some user vms are referencing it"); - callback.complete(result); + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } } + } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { @@ -336,29 +326,17 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } try { - /*String secondaryStoragePoolUrl = secStore.getUri(); - Long dcId = snapshot.getDataCenterId(); - Long accountId = snapshot.getAccountId(); - Long volumeId = snapshot.getVolumeId(); - - String backupOfSnapshot = snapshotObj; - if (backupOfSnapshot == null) { - callback.complete(result); - return; - } + String secondaryStoragePoolUrl = secStore.getUri(); DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId, - backupOfSnapshot, false); + secStore.getTO(), secondaryStoragePoolUrl, null, null, null, + snapshotObj.getPath(), false); EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); - if ((answer != null) && answer.getResult()) { - snapshot.setBackupSnapshotId(null); - snapshotDao.update(snapshotObj.getId(), snapshot); - } else if (answer != null) { + if (answer != null && !answer.getResult()) { result.setResult(answer.getDetails()); - }*/ + } } catch (Exception e) { s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); result.setResult(e.toString()); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 922cc3412d8..7fee53c1271 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -88,6 +88,8 @@ import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; import com.cloud.configuration.Config; @@ -253,6 +255,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject VolumeManager _volumeMgr; @Inject ImageStoreDao _imageStoreDao; @Inject EndPointSelector _epSelector; + @Inject UserVmJoinDao _userVmJoinDao; @Inject ConfigurationServer _configServer; @@ -1122,6 +1125,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template.getFormat() != ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid iso."); } + + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); + // check if there is any VM using this ISO. + if (!userVmUsingIso.isEmpty()) { + throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); + } if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) { throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index c93b99a1f11..93241760f3e 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -45,6 +45,7 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.cloudstack.storage.template.DownloadManager; @@ -161,7 +162,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S protected String _parent = "/mnt/SecStorage"; final private String _tmpltDir = "/var/cloudstack/template"; final private String _tmpltpp = "template.properties"; - private String createTemplateFromSnapshotXenScript; + protected String createTemplateFromSnapshotXenScript; @Override public void disconnected() { @@ -223,7 +224,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return Answer.createUnsupportedCommandAnswer(cmd); } } - + protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); @@ -353,7 +354,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S command.add("-s", snapshotName); command.add("-n", templateName); command.add("-t", destPath); - command.execute(); + String result = command.execute(); + + if (result != null && !result.equalsIgnoreCase("")) { + return new CopyCmdAnswer(result); + } Map params = new HashMap(); params.put(StorageLayer.InstanceConfigKey, _storage); @@ -1109,9 +1114,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) { - - final String lPath = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId) + File.pathSeparator - + (deleteAllFlag ? "*" : "*" + name + "*"); + String lPath = null; + int index = name.lastIndexOf(File.separator); + String snapshotPath = name.substring(0, index); + if (deleteAllFlag) { + lPath = this.getRootDir(secondaryStorageUrl) + File.separator + snapshotPath + File.separator + "*"; + } else { + lPath = this.getRootDir(secondaryStorageUrl) + File.separator + name + "*"; + } final String result = deleteLocalFile(lPath); From ed065418b6ed3a3b1aa6a26b7557cecba97423f4 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 14 May 2013 21:57:44 -0700 Subject: [PATCH 186/303] add license header --- .../storage/test/MockLocalHostEndPoint.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java index 31901e24d6b..28a586f83e5 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java @@ -1,3 +1,21 @@ +/* + * 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.test; import org.apache.cloudstack.storage.LocalHostEndpoint; From 8de401caadac92a1806811721c198e4fe87d7cd0 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 15 May 2013 14:08:09 -0700 Subject: [PATCH 187/303] Fix CLOUDSTACK-2520: Invoke parent constructor to set result state to default true to avoid attachVolume error. --- .../org/apache/cloudstack/storage/command/AttachAnswer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java index 1ddcd7dce8d..092ec63df44 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java @@ -26,8 +26,9 @@ public class AttachAnswer extends Answer { public AttachAnswer() { super(null); } - + public AttachAnswer(DiskTO disk) { + super(null); this.setDisk(disk); } public AttachAnswer(String errMsg) { From 4740f84c192c856e10b5060bfcc1c8f21da0f508 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 15 May 2013 14:47:23 -0700 Subject: [PATCH 188/303] Fix CLOUDSTACK-2482: NPE in createVolume when displayVolume parameter is not passed. --- .../cloudstack/api/command/user/volume/CreateVolumeCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java index 86a494b8848..107af1195a9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/CreateVolumeCmd.java @@ -117,7 +117,7 @@ public class CreateVolumeCmd extends BaseAsyncCreateCmd { } public Boolean getDisplayVolume() { - return displayVolume; + return displayVolume != null ? displayVolume : Boolean.TRUE; } ///////////////////////////////////////////////////// From 62a9daa5d679c95cb9c1e605f2df16b5439fff2e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 15 May 2013 15:52:46 -0700 Subject: [PATCH 189/303] Properly invoke parent constructor to default Answer result to true. --- api/src/com/cloud/agent/api/Answer.java | 1 + core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java | 1 + core/src/com/cloud/agent/api/storage/CreateAnswer.java | 1 + .../cloud/agent/api/storage/CreatePrivateTemplateAnswer.java | 4 +++- core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java | 2 +- core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java | 2 +- .../agent/api/storage/ManageVolumeAvailabilityAnswer.java | 1 + .../cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java | 1 + core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java | 2 +- core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java | 4 +++- 10 files changed, 14 insertions(+), 5 deletions(-) diff --git a/api/src/com/cloud/agent/api/Answer.java b/api/src/com/cloud/agent/api/Answer.java index 655f4470097..9d106115d91 100755 --- a/api/src/com/cloud/agent/api/Answer.java +++ b/api/src/com/cloud/agent/api/Answer.java @@ -23,6 +23,7 @@ public class Answer extends Command { protected String details; protected Answer() { + this(null); } public Answer(Command command) { diff --git a/core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java index 8c55ac3eecc..b9942b0c4b3 100644 --- a/core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java +++ b/core/src/com/cloud/agent/api/storage/CopyVolumeAnswer.java @@ -24,6 +24,7 @@ public class CopyVolumeAnswer extends Answer { private String volumePath; protected CopyVolumeAnswer() { + super(); } public CopyVolumeAnswer(Command command, boolean success, String details, String volumeFolder, String volumePath) { diff --git a/core/src/com/cloud/agent/api/storage/CreateAnswer.java b/core/src/com/cloud/agent/api/storage/CreateAnswer.java index ab6cc038604..cd2a7c8f00b 100644 --- a/core/src/com/cloud/agent/api/storage/CreateAnswer.java +++ b/core/src/com/cloud/agent/api/storage/CreateAnswer.java @@ -23,6 +23,7 @@ public class CreateAnswer extends Answer { VolumeTO volume; boolean requestTemplateReload = false; protected CreateAnswer() { + super(); } public CreateAnswer(CreateCommand cmd, VolumeTO volume) { diff --git a/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java b/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java index 83db84d8b87..37ebbfe4082 100644 --- a/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java +++ b/core/src/com/cloud/agent/api/storage/CreatePrivateTemplateAnswer.java @@ -27,7 +27,9 @@ public class CreatePrivateTemplateAnswer extends Answer { private String _uniqueName; private ImageFormat _format; - public CreatePrivateTemplateAnswer() {} + public CreatePrivateTemplateAnswer() { + super(); + } public CreatePrivateTemplateAnswer(Command cmd, boolean success, String result, String path, long virtualSize, long physicalSize, String uniqueName, ImageFormat format) { diff --git a/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java b/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java index 4155a632384..a3542cf6083 100644 --- a/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java +++ b/core/src/com/cloud/agent/api/storage/ListTemplateAnswer.java @@ -26,7 +26,7 @@ public class ListTemplateAnswer extends Answer { private Map templateInfos; public ListTemplateAnswer() { - + super(); } public ListTemplateAnswer(String secUrl, Map templateInfos) { diff --git a/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java index 31ea09b7d7c..9995d4b715e 100755 --- a/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java +++ b/core/src/com/cloud/agent/api/storage/ListVolumeAnswer.java @@ -26,7 +26,7 @@ public class ListVolumeAnswer extends Answer { private Map templateInfos; public ListVolumeAnswer() { - + super(); } public ListVolumeAnswer(String secUrl, Map templateInfos) { diff --git a/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java b/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java index edd283090b1..e8e0d20a074 100644 --- a/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java +++ b/core/src/com/cloud/agent/api/storage/ManageVolumeAvailabilityAnswer.java @@ -22,6 +22,7 @@ import com.cloud.agent.api.Command; public class ManageVolumeAvailabilityAnswer extends Answer { protected ManageVolumeAvailabilityAnswer() { + super(); } public ManageVolumeAvailabilityAnswer(Command command, boolean success, String details) { diff --git a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java index a5a6c49e9ab..6300fee84ec 100644 --- a/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java +++ b/core/src/com/cloud/agent/api/storage/PrimaryStorageDownloadAnswer.java @@ -23,6 +23,7 @@ public class PrimaryStorageDownloadAnswer extends Answer { private long templateSize = 0L; protected PrimaryStorageDownloadAnswer() { + super(); } public PrimaryStorageDownloadAnswer(String detail) { diff --git a/core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java b/core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java index 3434b985aaa..9d4c974e5a7 100644 --- a/core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java +++ b/core/src/com/cloud/agent/api/storage/ResizeVolumeAnswer.java @@ -22,7 +22,7 @@ public class ResizeVolumeAnswer extends Answer { private long newSize; protected ResizeVolumeAnswer() { - + super(); } public ResizeVolumeAnswer(ResizeVolumeCommand cmd, boolean result, String details, long newSize) { diff --git a/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java b/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java index 9660136b9e0..b328c907553 100644 --- a/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java +++ b/core/src/com/cloud/agent/api/storage/UpgradeDiskAnswer.java @@ -21,7 +21,9 @@ import com.cloud.agent.api.Command; public class UpgradeDiskAnswer extends Answer { - public UpgradeDiskAnswer() {} + public UpgradeDiskAnswer() { + super(); + } public UpgradeDiskAnswer(Command cmd, boolean success, String details) { super(cmd, success, details); From 7ffb6d8464f5265c7bb9c4c369eb306ba361f0ca Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 15 May 2013 16:52:28 -0700 Subject: [PATCH 190/303] Fix DettachAnswer to have default result state for CLOUDSTACK-2526. --- .../org/apache/cloudstack/storage/command/DettachAnswer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java index 9019e0cfa59..6606a7fd743 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java @@ -26,8 +26,9 @@ public class DettachAnswer extends Answer { public DettachAnswer() { super(null); } - + public DettachAnswer(DiskTO disk) { + super(null); this.setDisk(disk); } public DettachAnswer(String errMsg) { From d5050d3157ff47dc8b630740adee532f0fa6f433 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 15 May 2013 18:53:22 -0700 Subject: [PATCH 191/303] Fix ExtractVolume bug in generating URL. --- server/src/com/cloud/storage/upload/UploadMonitorImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index b9cee66028f..9e6cfeaae3a 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -286,7 +286,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { throw new CloudRuntimeException(errorString); } - CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreVO)secStore).getParent(), path, uuid); + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity)secStore).getMountPoint(), path, uuid); Answer ans = ep.sendMessage(cmd); if (ans == null || !ans.getResult()) { errorString = "Unable to create a link for " +type+ " id:"+entityId + "," + ans.getDetails(); From b66c4849050a109409cb9f2f6b6cb011d0e89783 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 15 May 2013 18:54:55 -0700 Subject: [PATCH 192/303] Fix size issue in copying template from S3 to cache storage to make system vm up. --- .../storage/datastore/db/TemplateDataStoreVO.java | 2 +- .../cloudstack/storage/image/TemplateServiceImpl.java | 4 ++-- .../cloudstack/storage/volume/VolumeServiceImpl.java | 1 + .../storage/secondary/SecondaryStorageManagerImpl.java | 3 +++ .../storage/resource/NfsSecondaryStorageResource.java | 7 +++++-- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index ea50d88f978..44bda70a00b 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -263,7 +263,7 @@ public class TemplateDataStoreVO implements StateObject ssStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); for( DataStore ssStore : ssStores ) { + if (!(ssStore.getTO() instanceof NfsTO )) + continue; // only do this for Nfs String secUrl = ssStore.getUri(); SecStorageSetupCommand setupCmd = null; if (!_useSSlCopy) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 93241760f3e..1125d7fdb50 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -224,7 +224,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return Answer.createUnsupportedCommandAnswer(cmd); } } - + protected Answer copyFromS3ToNfs(CopyCommand cmd, DataTO srcData, S3TO s3, DataTO destData, NfsTO destImageStore) { final String storagePath = destImageStore.getUrl(); final String destPath = destData.getPath(); @@ -308,6 +308,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String finalFileName = templateFilename; String finalDownloadPath = destPath + File.separator + templateFilename; + // compute the size of + long size = this._storage.getSize(downloadPath + File.separator + templateFilename); DataTO newDestTO = null; @@ -315,6 +317,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S TemplateObjectTO newTemplTO = new TemplateObjectTO(); newTemplTO.setPath(finalDownloadPath); newTemplTO.setName(finalFileName); + newTemplTO.setSize(size); newDestTO = newTemplTO; } else { return new CopyCmdAnswer("not implemented yet"); @@ -355,7 +358,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S command.add("-n", templateName); command.add("-t", destPath); String result = command.execute(); - + if (result != null && !result.equalsIgnoreCase("")) { return new CopyCmdAnswer(result); } From 2dc076f232181c7534f743c1dec7416c069f7066 Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Wed, 15 May 2013 12:51:08 +0530 Subject: [PATCH 193/303] CLOUDSTACK-2487: Show error while adding acl_item to default ACL --- .../src/com/cloud/network/vpc/NetworkACLServiceImpl.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java index ac59fab7ba2..00c90d5164e 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLServiceImpl.java @@ -216,8 +216,8 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ throw new InvalidParameterValueException("Network ACL can be created just for networks of type " + Networks.TrafficType.Guest); } - if(aclId != NetworkACL.DEFAULT_DENY) { - //ACL is not default DENY + if(aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) { + //ACL is not default DENY/ALLOW // ACL should be associated with a VPC Vpc vpc = _vpcMgr.getVpc(acl.getVpcId()); if(vpc == null){ @@ -254,6 +254,10 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ throw new InvalidParameterValueException("Unable to find specified ACL"); } + if((aclId == NetworkACL.DEFAULT_DENY) || (aclId == NetworkACL.DEFAULT_ALLOW)){ + throw new InvalidParameterValueException("Default ACL cannot be modified"); + } + Vpc vpc = _vpcMgr.getVpc(acl.getVpcId()); if(vpc == null){ throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL"); From c75b1894bca727784a1f371252bd3841ec6250e2 Mon Sep 17 00:00:00 2001 From: Kishan Kavala Date: Wed, 15 May 2013 14:20:29 +0530 Subject: [PATCH 194/303] Updated network acl service test to avoid default ACL modification --- server/test/com/cloud/vpc/NetworkACLServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/test/com/cloud/vpc/NetworkACLServiceTest.java b/server/test/com/cloud/vpc/NetworkACLServiceTest.java index 7cc7200718a..9a368b94ae4 100644 --- a/server/test/com/cloud/vpc/NetworkACLServiceTest.java +++ b/server/test/com/cloud/vpc/NetworkACLServiceTest.java @@ -83,7 +83,7 @@ public class NetworkACLServiceTest extends TestCase{ createACLItemCmd = new CreateNetworkACLCmd(){ @Override public Long getACLId(){ - return 1L; + return 3L; } @Override From 4c9ca2b50231d1df203d93df82280b8021f18a4d Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 15 May 2013 14:25:39 +0530 Subject: [PATCH 195/303] CLOUDSTACK-2459 Fix the scale vm tests --- server/test/com/cloud/vm/UserVmManagerTest.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/server/test/com/cloud/vm/UserVmManagerTest.java b/server/test/com/cloud/vm/UserVmManagerTest.java index 939ecdcc185..6a9711401c9 100755 --- a/server/test/com/cloud/vm/UserVmManagerTest.java +++ b/server/test/com/cloud/vm/UserVmManagerTest.java @@ -246,8 +246,8 @@ public class UserVmManagerTest { } - // Test scaleVm on incompatible HV. - //@Test(expected=InvalidParameterValueException.class) + // Test scaleVm on equal service offerings. + @Test(expected=InvalidParameterValueException.class) public void testScaleVMF2() throws Exception { ScaleVMCmd cmd = new ScaleVMCmd(); @@ -261,14 +261,11 @@ public class UserVmManagerTest { serviceOfferingIdField.setAccessible(true); serviceOfferingIdField.set(cmd, 1L); - //UserContext.current().setEventDetails("Vm Id: "+getId()); - // Account account = (Account) new AccountVO("testaccount", 1L, "networkdomain", (short) 0, 1); - //AccountVO(String accountName, long domainId, String networkDomain, short type, int regionId) - // UserContext.registerContext(1, account, null, true); when(_vmInstanceDao.findById(anyLong())).thenReturn(_vmInstance); doReturn(Hypervisor.HypervisorType.XenServer).when(_vmInstance).getHypervisorType(); + doReturn(VirtualMachine.State.Running).when(_vmInstance).getState(); doNothing().when(_accountMgr).checkAccess(_account, null, true, _templateMock); @@ -285,8 +282,8 @@ public class UserVmManagerTest { } - // Test scaleVm for Stopped vm. Full positive test. - //@Test + // Test scaleVm for Stopped vm. + @Test(expected=InvalidParameterValueException.class) public void testScaleVMF3() throws Exception { ScaleVMCmd cmd = new ScaleVMCmd(); @@ -316,10 +313,12 @@ public class UserVmManagerTest { when(_configMgr.getServiceOffering(1L)).thenReturn(so1); doReturn(VirtualMachine.State.Stopped).when(_vmInstance).getState(); + when(_vmDao.findById(anyLong())).thenReturn(null); + doReturn(true).when(_itMgr).upgradeVmDb(anyLong(),anyLong()); - when(_vmDao.findById(anyLong())).thenReturn(_vmMock); + //when(_vmDao.findById(anyLong())).thenReturn(_vmMock); _userVmMgr.upgradeVirtualMachine(cmd); From 50eeae81da0a9d88479ece5e6c0d74449e26cd93 Mon Sep 17 00:00:00 2001 From: Prasanna Santhanam Date: Wed, 15 May 2013 14:51:37 +0530 Subject: [PATCH 196/303] don't let requests logs requests logs to the logger making it hard to distinguish marvin logs from http logs. Signed-off-by: Prasanna Santhanam --- tools/marvin/marvin/cloudstackConnection.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/marvin/marvin/cloudstackConnection.py b/tools/marvin/marvin/cloudstackConnection.py index 803911721e9..b5ff5bf7b3f 100644 --- a/tools/marvin/marvin/cloudstackConnection.py +++ b/tools/marvin/marvin/cloudstackConnection.py @@ -20,6 +20,7 @@ import urllib import base64 import hmac import hashlib +import logging import time import cloudstackException from cloudstackAPI import * @@ -37,6 +38,7 @@ class cloudConnection(object): apiKey=None, securityKey=None, asyncTimeout=3600, logging=None, scheme='http', path='client/api'): + self.loglevel() #Turn off requests logs self.apiKey = apiKey self.securityKey = securityKey self.mgtSvr = mgtSvr @@ -65,6 +67,13 @@ class cloudConnection(object): self.asyncTimeout, self.logging, self.protocol, self.path) + def loglevel(self, lvl=logging.WARNING): + """ + Turns off the INFO/DEBUG logs from `requests` + """ + requests_log = logging.getLogger("requests") + requests_log.setLevel(lvl) + def poll(self, jobid, response): """ polls the completion of a given jobid From 88422248ccbf2585f7b9c25c78e4732c5a8b7158 Mon Sep 17 00:00:00 2001 From: Sanjay Tripathi Date: Fri, 26 Apr 2013 16:47:56 +0530 Subject: [PATCH 197/303] CLOUDSTACK-1904: API : UI : Admin can not delete Events/Archive from other accounts --- .../command/user/event/DeleteEventsCmd.java | 1 - .../src/com/cloud/domain/dao/DomainDao.java | 9 ++++--- .../com/cloud/domain/dao/DomainDaoImpl.java | 18 +++++++++++-- .../src/com/cloud/event/dao/EventDao.java | 2 +- .../src/com/cloud/event/dao/EventDaoImpl.java | 27 ++++++++++--------- .../src/com/cloud/user/dao/AccountDao.java | 1 + .../com/cloud/user/dao/AccountDaoImpl.java | 19 +++++++++++-- .../cloud/server/ManagementServerImpl.java | 24 +++++++++++++++-- .../cloud/event/EventControlsUnitTest.java | 3 +-- 9 files changed, 77 insertions(+), 27 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java index 55ca92a5dfe..a03e6d9f7df 100644 --- a/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/event/DeleteEventsCmd.java @@ -25,7 +25,6 @@ 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.response.AlertResponse; import org.apache.cloudstack.api.response.EventResponse; import org.apache.cloudstack.api.response.SuccessResponse; import org.apache.log4j.Logger; diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDao.java b/engine/schema/src/com/cloud/domain/dao/DomainDao.java index afeb0f462f4..cb1c1f2c4be 100644 --- a/engine/schema/src/com/cloud/domain/dao/DomainDao.java +++ b/engine/schema/src/com/cloud/domain/dao/DomainDao.java @@ -26,9 +26,10 @@ public interface DomainDao extends GenericDao { public DomainVO create(DomainVO domain); public DomainVO findDomainByPath(String domainPath); public boolean isChildDomain(Long parentId, Long childId); - DomainVO findImmediateChildForParent(Long parentId); - List findImmediateChildrenForParent(Long parentId); - List findAllChildren(String path, Long parentId); - List findInactiveDomains(); + DomainVO findImmediateChildForParent(Long parentId); + List findImmediateChildrenForParent(Long parentId); + List findAllChildren(String path, Long parentId); + List findInactiveDomains(); Set getDomainParentIds(long domainId); + List getDomainChildrenIds(String path); } diff --git a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java index c30ca5ef49a..9460a73dc57 100644 --- a/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java +++ b/engine/schema/src/com/cloud/domain/dao/DomainDaoImpl.java @@ -32,6 +32,7 @@ import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.utils.db.DB; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @@ -46,6 +47,7 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom protected SearchBuilder DomainPairSearch; protected SearchBuilder ImmediateChildDomainSearch; protected SearchBuilder FindAllChildrenSearch; + protected GenericSearchBuilder FindIdsOfAllChildrenSearch; protected SearchBuilder AllFieldsSearch; public DomainDaoImpl () { @@ -70,7 +72,12 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom FindAllChildrenSearch.and("path", FindAllChildrenSearch.entity().getPath(), SearchCriteria.Op.LIKE); FindAllChildrenSearch.and("id", FindAllChildrenSearch.entity().getId(), SearchCriteria.Op.NEQ); FindAllChildrenSearch.done(); - + + FindIdsOfAllChildrenSearch = createSearchBuilder(Long.class); + FindIdsOfAllChildrenSearch.selectField(FindIdsOfAllChildrenSearch.entity().getId()); + FindIdsOfAllChildrenSearch.and("path", FindIdsOfAllChildrenSearch.entity().getPath(), SearchCriteria.Op.LIKE); + FindIdsOfAllChildrenSearch.done(); + AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ); AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ); @@ -221,7 +228,14 @@ public class DomainDaoImpl extends GenericDaoBase implements Dom sc.setParameters("id", parentId); return listBy(sc); } - + + @Override + public List getDomainChildrenIds(String path){ + SearchCriteria sc = FindIdsOfAllChildrenSearch.create(); + sc.setParameters("path", path+"%"); + return customSearch(sc, null); + } + @Override public boolean isChildDomain(Long parentId, Long childId) { if ((parentId == null) || (childId == null)) { diff --git a/engine/schema/src/com/cloud/event/dao/EventDao.java b/engine/schema/src/com/cloud/event/dao/EventDao.java index da5f47a90b4..9454ce717de 100644 --- a/engine/schema/src/com/cloud/event/dao/EventDao.java +++ b/engine/schema/src/com/cloud/event/dao/EventDao.java @@ -31,7 +31,7 @@ public interface EventDao extends GenericDao { EventVO findCompletedEvent(long startId); - public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, Long accountId); + public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, List accountIds); public void archiveEvents(List events); diff --git a/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java b/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java index 6ba59c56b0a..0d3d38a0204 100644 --- a/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java +++ b/engine/schema/src/com/cloud/event/dao/EventDaoImpl.java @@ -49,7 +49,7 @@ public class EventDaoImpl extends GenericDaoBase implements Event ToArchiveOrDeleteEventSearch = createSearchBuilder(); ToArchiveOrDeleteEventSearch.and("id", ToArchiveOrDeleteEventSearch.entity().getId(), Op.IN); ToArchiveOrDeleteEventSearch.and("type", ToArchiveOrDeleteEventSearch.entity().getType(), Op.EQ); - ToArchiveOrDeleteEventSearch.and("accountId", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.EQ); + ToArchiveOrDeleteEventSearch.and("accountIds", ToArchiveOrDeleteEventSearch.entity().getAccountId(), Op.IN); ToArchiveOrDeleteEventSearch.and("createDateL", ToArchiveOrDeleteEventSearch.entity().getCreateDate(), Op.LT); ToArchiveOrDeleteEventSearch.done(); } @@ -76,7 +76,7 @@ public class EventDaoImpl extends GenericDaoBase implements Event } @Override - public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, Long accountId) { + public List listToArchiveOrDeleteEvents(List ids, String type, Date olderThan, List accountIds) { SearchCriteria sc = ToArchiveOrDeleteEventSearch.create(); if (ids != null) { sc.setParameters("id", ids.toArray(new Object[ids.size()])); @@ -87,23 +87,24 @@ public class EventDaoImpl extends GenericDaoBase implements Event if (olderThan != null) { sc.setParameters("createDateL", olderThan); } - if (accountId != null) { - sc.setParameters("accountId", accountId); + if (accountIds != null && !accountIds.isEmpty()) { + sc.setParameters("accountIds", accountIds.toArray(new Object[accountIds.size()])); } return search(sc, null); } @Override public void archiveEvents(List events) { - - Transaction txn = Transaction.currentTxn(); - txn.start(); - for (EventVO event : events) { - event = lockRow(event.getId(), true); - event.setArchived(true); - update(event.getId(), event); - txn.commit(); + if (events != null && !events.isEmpty()) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + for (EventVO event : events) { + event = lockRow(event.getId(), true); + event.setArchived(true); + update(event.getId(), event); + txn.commit(); + } + txn.close(); } - txn.close(); } } diff --git a/engine/schema/src/com/cloud/user/dao/AccountDao.java b/engine/schema/src/com/cloud/user/dao/AccountDao.java index 3b7fa66434e..204da394a69 100644 --- a/engine/schema/src/com/cloud/user/dao/AccountDao.java +++ b/engine/schema/src/com/cloud/user/dao/AccountDao.java @@ -49,4 +49,5 @@ public interface AccountDao extends GenericDao { //returns only non-removed account Account findActiveAccount(String accountName, Long domainId); Account findActiveNonProjectAccount(String accountName, Long domainId); + List getAccountIdsForDomains(List ids); } diff --git a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java index 892fdcd548d..aa67e86bf70 100755 --- a/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java +++ b/engine/schema/src/com/cloud/user/dao/AccountDaoImpl.java @@ -35,8 +35,10 @@ import com.cloud.utils.Pair; import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDaoBase; +import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; @Component @@ -54,7 +56,8 @@ public class AccountDaoImpl extends GenericDaoBase implements A protected final SearchBuilder CleanupForRemovedAccountsSearch; protected final SearchBuilder CleanupForDisabledAccountsSearch; protected final SearchBuilder NonProjectAccountSearch; - + protected final GenericSearchBuilder AccountIdsSearch; + public AccountDaoImpl() { AllFieldsSearch = createSearchBuilder(); AllFieldsSearch.and("accountName", AllFieldsSearch.entity().getAccountName(), SearchCriteria.Op.EQ); @@ -91,6 +94,11 @@ public class AccountDaoImpl extends GenericDaoBase implements A NonProjectAccountSearch.and("state", NonProjectAccountSearch.entity().getState(), SearchCriteria.Op.EQ); NonProjectAccountSearch.and("type", NonProjectAccountSearch.entity().getType(), SearchCriteria.Op.NEQ); NonProjectAccountSearch.done(); + + AccountIdsSearch = createSearchBuilder(Long.class); + AccountIdsSearch.selectField(AccountIdsSearch.entity().getId()); + AccountIdsSearch.and("ids", AccountIdsSearch.entity().getDomainId(), Op.IN); + AccountIdsSearch.done(); } @Override @@ -263,5 +271,12 @@ public class AccountDaoImpl extends GenericDaoBase implements A } } } - + + @Override + public List getAccountIdsForDomains(List domainIds) { + SearchCriteria sc = AccountIdsSearch.create(); + sc.setParameters("ids", domainIds.toArray(new Object[domainIds.size()])); + return customSearch(sc, null); + } + } diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index c3913a5d77b..6e8ce86909a 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -957,10 +957,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public boolean archiveEvents(ArchiveEventsCmd cmd) { + Account caller = UserContext.current().getCaller(); List ids = cmd.getIds(); boolean result =true; + List permittedAccountIds = new ArrayList(); - List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL && caller.getType() == Account.ACCOUNT_TYPE_PROJECT) { + permittedAccountIds.add(caller.getId()); + } else { + DomainVO domain = _domainDao.findById(caller.getDomainId()); + List permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath()); + permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds); + } + + List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), permittedAccountIds); ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents); @@ -974,10 +984,20 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe @Override public boolean deleteEvents(DeleteEventsCmd cmd) { + Account caller = UserContext.current().getCaller(); List ids = cmd.getIds(); boolean result =true; + List permittedAccountIds = new ArrayList(); - List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), cmd.getEntityOwnerId()); + if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL || caller.getType() == Account.ACCOUNT_TYPE_PROJECT) { + permittedAccountIds.add(caller.getId()); + } else { + DomainVO domain = _domainDao.findById(caller.getDomainId()); + List permittedDomainIds = _domainDao.getDomainChildrenIds(domain.getPath()); + permittedAccountIds = _accountDao.getAccountIdsForDomains(permittedDomainIds); + } + + List events = _eventDao.listToArchiveOrDeleteEvents(ids, cmd.getType(), cmd.getOlderThan(), permittedAccountIds); ControlledEntity[] sameOwnerEvents = events.toArray(new ControlledEntity[events.size()]); _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, sameOwnerEvents); diff --git a/server/test/com/cloud/event/EventControlsUnitTest.java b/server/test/com/cloud/event/EventControlsUnitTest.java index 3c2527565c9..e2a86cdb4be 100644 --- a/server/test/com/cloud/event/EventControlsUnitTest.java +++ b/server/test/com/cloud/event/EventControlsUnitTest.java @@ -18,7 +18,6 @@ package com.cloud.event; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; @@ -58,7 +57,7 @@ public class EventControlsUnitTest extends TestCase{ _mgmtServer._eventDao = _eventDao; _mgmtServer._accountMgr = _accountMgr; doNothing().when(_accountMgr).checkAccess(any(Account.class), any(AccessType.class), any(Boolean.class), any(ControlledEntity.class)); - when(_eventDao.listToArchiveOrDeleteEvents(anyList(), anyString(), any(Date.class), anyLong())).thenReturn(_events); + when(_eventDao.listToArchiveOrDeleteEvents(anyList(), anyString(), any(Date.class), anyList())).thenReturn(_events); } @After From ca0d2ef8c2244f40cb7e47601fb6de8277dbb6e5 Mon Sep 17 00:00:00 2001 From: Harikrishna Patnala Date: Wed, 15 May 2013 16:00:25 +0530 Subject: [PATCH 198/303] CLOUDSTACK-2085: VM weight on xen remain same as before vmscaleup ;because "Add-To-VCPUs-Params-Live.sh" is not getting copied on xs host Fixed by updating the patch files that has entries to copy scipts on xenserver. Here we added Add-To-VCPUs-Params-Live.sh Added a check on Host params whether host restricts Dynamic memory control(DMC) to able to allow scale up VM. If DMC is not enabled then static max and min are set to SO. Signed Off by - Nitin Mehta --- .../hypervisor/xen/resource/CitrixResourceBase.java | 8 +++++++- .../xen/resource/XenServer56FP1Resource.java | 13 +++++++++++-- .../xen/resource/CitrixResourceBaseTest.java | 8 ++++---- ...s-Params-Live.sh => add_to_vcpus_params_live.sh} | 0 scripts/vm/hypervisor/xenserver/vmops | 2 +- scripts/vm/hypervisor/xenserver/xcpserver/patch | 1 + scripts/vm/hypervisor/xenserver/xenserver56/patch | 1 + .../vm/hypervisor/xenserver/xenserver56fp1/patch | 1 + scripts/vm/hypervisor/xenserver/xenserver60/patch | 1 + 9 files changed, 27 insertions(+), 8 deletions(-) rename scripts/vm/hypervisor/xenserver/{Add-To-VCPUs-Params-Live.sh => add_to_vcpus_params_live.sh} (100%) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index cfb673f0be5..0828dc48877 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -691,7 +691,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vmSpec.getLimitCpuUse()) { long utilization = 0; // max CPU cap, default is unlimited utilization = ((long)speed * 100 * vmSpec.getCpus()) / _host.speed ; - vm.addToVCPUsParamsLive(conn, "cap", Long.toString(utilization)); + //vm.addToVCPUsParamsLive(conn, "cap", Long.toString(utilization)); currently xenserver doesnot support Xapi to add VCPUs params live. + callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", Long.toString(utilization), "vmname", vmSpec.getName() ); } //vm.addToVCPUsParamsLive(conn, "weight", Integer.toString(cpuWeight)); callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", Integer.toString(cpuWeight), "vmname", vmSpec.getName() ); @@ -724,6 +725,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe for (VM vm : vms) { VM.Record vmr = vm.getRecord(conn); try { + Map hostParams = new HashMap(); + hostParams = host.getLicenseParams(conn); + if (hostParams.get("restrict_dmc").equalsIgnoreCase("true")) { + throw new CloudRuntimeException("Host "+ _host.uuid + " does not support Dynamic Memory Control, so we cannot scale up the vm"); + } scaleVM(conn, vm, vmSpec, host); } catch (Exception e) { diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java index 0982158b2cd..d2b96e42f2c 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServer56FP1Resource.java @@ -142,8 +142,17 @@ public class XenServer56FP1Resource extends XenServer56Resource { record.actionsAfterShutdown = Types.OnNormalExit.DESTROY; record.memoryDynamicMax = vmSpec.getMaxRam(); record.memoryDynamicMin = vmSpec.getMinRam(); - record.memoryStaticMax = 8589934592L; //128GB - record.memoryStaticMin = 134217728L; //128MB + Map hostParams = new HashMap(); + hostParams = host.getLicenseParams(conn); + if (hostParams.get("restrict_dmc").equalsIgnoreCase("false")) { + record.memoryStaticMax = 8589934592L; //8GB + record.memoryStaticMin = 134217728L; //128MB + } else { + s_logger.warn("Host "+ _host.uuid + " does not support Dynamic Memory Control, so we cannot scale up the vm"); + record.memoryStaticMax = vmSpec.getMaxRam(); + record.memoryStaticMin = vmSpec.getMinRam(); + } + if (guestOsTypeName.toLowerCase().contains("windows")) { record.VCPUsMax = (long) vmSpec.getCpus(); } else { diff --git a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java index 7392cb1d53e..877e3bc5120 100644 --- a/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java +++ b/plugins/hypervisors/xen/test/com/cloud/hypervisor/xen/resource/CitrixResourceBaseTest.java @@ -110,7 +110,7 @@ public class CitrixResourceBaseTest { @Test public void testScaleVMF2() throws Types.XenAPIException, XmlRpcException { - doReturn(null).when(vm).setMemoryDynamicRangeAsync(conn, 536870912L, 536870912L); + doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L); doReturn(1).when(vmSpec).getCpus(); doNothing().when(vm).setVCPUsNumberLive(conn, 1L); doReturn(500).when(vmSpec).getSpeed(); @@ -129,12 +129,12 @@ public class CitrixResourceBaseTest { @Test public void testScaleVMF3() throws Types.XenAPIException, XmlRpcException { - doReturn(null).when(vm).setMemoryDynamicRangeAsync(conn, 536870912L, 536870912L); + doNothing().when(vm).setMemoryDynamicRange(conn, 536870912L, 536870912L); doReturn(1).when(vmSpec).getCpus(); doNothing().when(vm).setVCPUsNumberLive(conn, 1L); doReturn(500).when(vmSpec).getSpeed(); doReturn(true).when(vmSpec).getLimitCpuUse(); - doNothing().when(vm).addToVCPUsParamsLive(conn, "cap", "100"); + doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "100", "vmname", "i-2-3-VM"); Map args = (Map)mock(HashMap.class); when(host.callPlugin(conn, "vmops", "add_to_VCPUs_params_live", args)).thenReturn("Success"); doReturn(null).when(_resource).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM"); @@ -143,6 +143,6 @@ public class CitrixResourceBaseTest { verify(vmSpec, times(1)).getLimitCpuUse(); verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "weight", "value", "253", "vmname", "i-2-3-VM"); - verify(vm, times(1)).addToVCPUsParamsLive(conn, "cap", "100"); + verify(_resource, times(1)).callHostPlugin(conn, "vmops", "add_to_VCPUs_params_live", "key", "cap", "value", "100", "vmname", "i-2-3-VM"); } } \ No newline at end of file diff --git a/scripts/vm/hypervisor/xenserver/Add-To-VCPUs-Params-Live.sh b/scripts/vm/hypervisor/xenserver/add_to_vcpus_params_live.sh similarity index 100% rename from scripts/vm/hypervisor/xenserver/Add-To-VCPUs-Params-Live.sh rename to scripts/vm/hypervisor/xenserver/add_to_vcpus_params_live.sh diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops index 60fb8ab0b21..d18eca836b8 100755 --- a/scripts/vm/hypervisor/xenserver/vmops +++ b/scripts/vm/hypervisor/xenserver/vmops @@ -48,7 +48,7 @@ def add_to_VCPUs_params_live(session, args): value = args['value'] vmname = args['vmname'] try: - cmd = ["bash", "/opt/xensource/bin/Add-To-VCPUs-Params-Live.sh", vmname, key, value] + cmd = ["bash", "/opt/xensource/bin/add_to_vcpus_params_live.sh", vmname, key, value] txt = util.pread2(cmd) except: return 'false' diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch index bfecd0c8e04..a275df4a48b 100644 --- a/scripts/vm/hypervisor/xenserver/xcpserver/patch +++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch @@ -64,3 +64,4 @@ cloud-prepare-upgrade.sh=..,0755,/opt/xensource/bin getRouterStatus.sh=../../../../network/domr/,0755,/opt/xensource/bin bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin getDomRVersion.sh=../../../../network/domr/,0755,/opt/xensource/bin +add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch index 1be14ea62db..5c4673df247 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch @@ -65,4 +65,5 @@ bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins s3xen=..,0755,/etc/xapi.d/plugins +add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch index dd31e441b4f..c7c58b98374 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch @@ -64,4 +64,5 @@ bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins s3xen=..,0755,/etc/xapi.d/plugins +add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch index 787f474739a..6d819791d3d 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver60/patch +++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch @@ -69,4 +69,5 @@ bumpUpPriority.sh=../../../../network/domr/,0755,/opt/xensource/bin swift=..,0755,/opt/xensource/bin swiftxen=..,0755,/etc/xapi.d/plugins s3xen=..,0755,/etc/xapi.d/plugins +add_to_vcpus_params_live.sh=..,0755,/opt/xensource/bin From 1f5ae4bae38d0e13d564f0c1f072404152568940 Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 15 May 2013 15:53:36 +0530 Subject: [PATCH 199/303] CLOUDSTACK:685 Fix user stat collection in PrepareStop part of VirtualNetworkApplianceImpl --- .../VirtualNetworkApplianceManagerImpl.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 7bbdba6b232..5de2388742d 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -3889,26 +3889,29 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V String privateIP = router.getPrivateIpAddress(); if (privateIP != null) { + boolean forVpc = router.getVpcId() != null; List routerNics = _nicDao.listByVmId(router.getId()); for (Nic routerNic : routerNics) { Network network = _networkModel.getNetwork(routerNic.getNetworkId()); - if (network.getTrafficType() == TrafficType.Public) { - boolean forVpc = router.getVpcId() != null; + //Send network usage command for public nic in VPC VR + //Send network usage command for isolated guest nic of non VPC VR + if ((forVpc && network.getTrafficType() == TrafficType.Public) || (!forVpc && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Isolated)) { final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIp4Address()); + String routerType = router.getType().toString(); UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), - router.getDataCenterId(), network.getId(), null, router.getId(), router.getType().toString()); + router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); NetworkUsageAnswer answer = null; try { answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); } catch (Exception e) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); + s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e); continue; } if (answer != null) { if (!answer.getResult()) { - s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); + s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId() + "; details: " + answer.getDetails()); continue; } Transaction txn = Transaction.open(Transaction.CLOUD_DB); @@ -3919,26 +3922,26 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } txn.start(); UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), - router.getDataCenterId(), network.getId(), null, router.getId(), router.getType().toString()); + router.getDataCenterId(), network.getId(), (forVpc ? routerNic.getIp4Address() : null), router.getId(), routerType); if (stats == null) { s_logger.warn("unable to find stats for account: " + router.getAccountId()); continue; } - if(previousStats != null - && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) - || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + if (previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + - "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + - answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + "Ignoring current answer. Router: " + answer.getRouterName() + " Rcvd: " + + answer.getBytesReceived() + "Sent: " + answer.getBytesSent()); continue; } if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName()+" Reported: " + answer.getBytesReceived() + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName() + " Reported: " + answer.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived()); } stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); @@ -3947,8 +3950,8 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V if (stats.getCurrentBytesSent() > answer.getBytesSent()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Received # of bytes that's less than the last one. " + - "Assuming something went wrong and persisting it. Router: " + - answer.getRouterName()+" Reported: " + answer.getBytesSent() + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName() + " Reported: " + answer.getBytesSent() + " Stored: " + stats.getCurrentBytesSent()); } stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); From 85789534f016c0ae5e5a4fe19c18938819d96e99 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Wed, 15 May 2013 15:40:23 +0530 Subject: [PATCH 200/303] CLOUDSTACK-2369 fixed adding same private gw twice --- .../src/com/cloud/network/vpc/dao/PrivateIpDao.java | 3 ++- .../com/cloud/network/vpc/dao/PrivateIpDaoImpl.java | 11 ++++++++++- server/src/com/cloud/network/NetworkServiceImpl.java | 4 +++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDao.java b/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDao.java index 02df92e9c67..ff8c26a9571 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDao.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDao.java @@ -70,6 +70,7 @@ public interface PrivateIpDao extends GenericDao{ */ PrivateIpVO findByIpAndVpcId(long vpcId, String ip4Address); - + + PrivateIpVO findByIpAndSourceNetworkIdAndVpcId(long networkId, String ip4Address, long vpcId); } diff --git a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java b/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java index ecab3bb6625..fe435c05175 100644 --- a/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java +++ b/engine/schema/src/com/cloud/network/vpc/dao/PrivateIpDaoImpl.java @@ -114,7 +114,16 @@ public class PrivateIpDaoImpl extends GenericDaoBase implemen sc.setParameters("networkId", networkId); return findOneBy(sc); } - + + @Override + public PrivateIpVO findByIpAndSourceNetworkIdAndVpcId(long networkId, String ip4Address, long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("ip", ip4Address); + sc.setParameters("networkId", networkId); + sc.setParameters("vpcId", vpcId); + return findOneBy(sc); + } + @Override public PrivateIpVO findByIpAndVpcId(long vpcId, String ip4Address) { SearchCriteria sc = AllFieldsSearch.create(); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index f3ec253d631..d3ef320a981 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -3813,10 +3813,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { s_logger.debug("Created private network " + privateNetwork); } else { s_logger.debug("Private network already exists: " + privateNetwork); + throw new InvalidParameterValueException("Private network for the vlan: " + vlan + " and cidr "+ cidr +" already exists " + + " in zone " + _configMgr.getZone(pNtwk.getDataCenterId()).getName()); } //add entry to private_ip_address table - PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkId(privateNetwork.getId(), startIp); + PrivateIpVO privateIp = _privateIpDao.findByIpAndSourceNetworkIdAndVpcId(privateNetwork.getId(), startIp, vpcId); if (privateIp != null) { throw new InvalidParameterValueException("Private ip address " + startIp + " already used for private gateway" + " in zone " + _configMgr.getZone(pNtwk.getDataCenterId()).getName()); From 738067077a184aa355005b53979be6c397920f82 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Wed, 15 May 2013 13:57:58 +0200 Subject: [PATCH 201/303] CLOUDSTACK-2515: Verify if the targetPath isn't null before comparing --- .../cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java index 8f58719e7be..e7e4bbf2c30 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/LibvirtStorageAdaptor.java @@ -465,7 +465,8 @@ public class LibvirtStorageAdaptor implements StorageAdaptor { StoragePool p = conn.storagePoolLookupByName(poolname); LibvirtStoragePoolDef pdef = getStoragePoolDef(conn, p); - if (pdef.getTargetPath().equals(path)) { + String targetPath = pdef.getTargetPath(); + if (targetPath != null && targetPath.equals(path)) { s_logger.debug("Storage pool utilizing path '" + path + "' already exists as pool " + poolname + ", undefining so we can re-define with correct name " + name); if (p.isPersistent() == 1) { From cf1fada372622fe610c18d17fdaf1589acc50d03 Mon Sep 17 00:00:00 2001 From: Pranav Saxena Date: Wed, 15 May 2013 18:01:10 +0530 Subject: [PATCH 202/303] CLOUDSTACK-2491:NTier: Creation of ACL Rule for protocol AH (51) and ESP (50) Fails --- ui/scripts/vpc.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js index 5d436f3536a..0c4a446485b 100644 --- a/ui/scripts/vpc.js +++ b/ui/scripts/vpc.js @@ -94,8 +94,8 @@ }, 'protocolnumber': {label:'Protocol Number',isDisabled:true,isHidden:true,edit:true}, - 'startport': { edit: true, label: 'label.start.port' }, - 'endport': { edit: true, label: 'label.end.port' }, + 'startport': { edit: true, label: 'label.start.port' , isOptional:true }, + 'endport': { edit: true, label: 'label.end.port' , isOptional:true}, 'networkid': { label: 'Select Tier', select: function(args) { @@ -165,7 +165,18 @@ else delete args.data.protocolnumber; + + if((args.data.protocol == 'tcp' || args.data.protocol == 'udp' || args.data.protocol == 'all') && (args.data.startport=="" || args.data.startport == undefined)){ + cloudStack.dialog.notice({message:_l('Start Port or End Port value should not be blank')}); + $(window).trigger('cloudStack.fullRefresh'); + } + else if((args.data.protocol == 'tcp' || args.data.protocol == 'udp' || args.data.protocol == 'all') && (args.data.endport=="" || args.data.endport == undefined)){ + cloudStack.dialog.notice({message:_l('Start Port or End Port value should not be blank')}); + $(window).trigger('cloudStack.fullRefresh'); + } + + else{ $.ajax({ url: createURL('createNetworkACL'), data: $.extend(args.data, { @@ -202,6 +213,7 @@ } }); } + } }, actions: { destroy: { From fd354dbd7c9a6a25a0a3560b6db530fc7f5ece72 Mon Sep 17 00:00:00 2001 From: Likitha Shetty Date: Tue, 14 May 2013 14:24:47 +0530 Subject: [PATCH 203/303] CLOUDSTACK-2116 Public IP addresses resource count of an account - number of ip addresses dedicated to an account plus the number of ip addresses belonging to the system that have been allocated to the account --- .../schema/src/com/cloud/dc/dao/VlanDao.java | 2 ++ .../src/com/cloud/dc/dao/VlanDaoImpl.java | 15 ++++++++++++ .../ConfigurationManagerImpl.java | 10 +++++++- .../com/cloud/network/NetworkManagerImpl.java | 16 ++++++------- .../ResourceLimitManagerImpl.java | 23 ++++++++++++++++++- 5 files changed, 56 insertions(+), 10 deletions(-) diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDao.java b/engine/schema/src/com/cloud/dc/dao/VlanDao.java index 605fb2020df..39fa818e26f 100755 --- a/engine/schema/src/com/cloud/dc/dao/VlanDao.java +++ b/engine/schema/src/com/cloud/dc/dao/VlanDao.java @@ -54,4 +54,6 @@ public interface VlanDao extends GenericDao { List listZoneWideNonDedicatedVlans(long zoneId); List listVlansByNetworkIdAndGateway(long networkid, String gateway); + + List listDedicatedVlans(long accountId); } diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java index e8c68b18a6b..eb3bde9d005 100755 --- a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -58,6 +58,7 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao protected SearchBuilder PhysicalNetworkVlanSearch; protected SearchBuilder ZoneWideNonDedicatedVlanSearch; protected SearchBuilder VlanGatewaysearch; + protected SearchBuilder DedicatedVlanSearch; protected SearchBuilder AccountVlanMapSearch; @@ -213,6 +214,13 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao ZoneWideNonDedicatedVlanSearch.done(); AccountVlanMapSearch.done(); + DedicatedVlanSearch = createSearchBuilder(); + AccountVlanMapSearch = _accountVlanMapDao.createSearchBuilder(); + AccountVlanMapSearch.and("accountId", AccountVlanMapSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + DedicatedVlanSearch.join("AccountVlanMapSearch", AccountVlanMapSearch, DedicatedVlanSearch.entity().getId(), AccountVlanMapSearch.entity().getVlanDbId(), JoinBuilder.JoinType.LEFTOUTER); + DedicatedVlanSearch.done(); + AccountVlanMapSearch.done(); + return result; } @@ -343,4 +351,11 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao return listBy(sc); } + @Override + public List listDedicatedVlans(long accountId) { + SearchCriteria sc = DedicatedVlanSearch.create(); + sc.setJoinParameters("AccountVlanMapSearch", "accountId", accountId); + return listBy(sc); + } + } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 045c333b862..28375358f64 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -2852,6 +2852,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid()); } + // increment resource count for dedicated public ip's + _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size())); } else if (podId != null) { // This VLAN is pod-wide, so create a PodVlanMapVO entry PodVlanMapVO podVlanMapVO = new PodVlanMapVO(podId, vlan.getId()); @@ -3122,6 +3124,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid()); } + + // increment resource count for dedicated public ip's + _resourceLimitMgr.incrementResourceCount(vlanOwner.getId(), ResourceType.public_ip, new Long(ips.size())); + return vlan; } @@ -3185,10 +3191,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati if (_accountVlanMapDao.remove(acctVln.get(0).getId())) { // generate usage events to remove dedication for every ip in the range for (IPAddressVO ip : ips) { - UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, acctVln.get(0).getId(), + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE, acctVln.get(0).getAccountId(), ip.getDataCenterId(), ip.getId(), ip.getAddress().toString(), ip.isSourceNat(), vlan.getVlanType().toString(), ip.getSystem(), ip.getClass().getName(), ip.getUuid()); } + // decrement resource count for dedicated public ip's + _resourceLimitMgr.decrementResourceCount(acctVln.get(0).getAccountId(), ResourceType.public_ip, new Long(ips.size())); return true; } else { return false; diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index d37f7c92159..88347240959 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -393,8 +393,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, addr.getSystem(), addr.getClass().getName(), addr.getUuid()); } - // don't increment resource count for direct ip addresses - if (addr.getAssociatedWithNetworkId() != null) { + // don't increment resource count for direct and dedicated ip addresses + if (addr.getAssociatedWithNetworkId() != null && !isIpDedicated(addr)) { _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip); } } @@ -639,10 +639,6 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L s_logger.debug("Associate IP address lock acquired"); } - // Check that the maximum number of public IPs for the given - // accountId will not be exceeded - _resourceLimitMgr.checkResourceLimit(accountToLock, ResourceType.public_ip); - txn.start(); // If account has dedicated Public IP ranges, allocate IP from the dedicated range @@ -667,6 +663,10 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L } if (!allocateFromDedicatedRange) { + // Check that the maximum number of public IPs for the given + // accountId will not be exceeded + _resourceLimitMgr.checkResourceLimit(accountToLock, ResourceType.public_ip); + List nonDedicatedVlans = _vlanDao.listZoneWideNonDedicatedVlans(zone.getId()); for (VlanVO nonDedicatedVlan : nonDedicatedVlans) { nonDedicatedVlanDbIds.add(nonDedicatedVlan.getId()); @@ -2963,8 +2963,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L if (ip.getState() != State.Releasing) { txn.start(); - // don't decrement resource count for direct ips - if (ip.getAssociatedWithNetworkId() != null) { + // don't decrement resource count for direct and dedicated ips + if (ip.getAssociatedWithNetworkId() != null && !isIpDedicated(ip)) { _resourceLimitMgr.decrementResourceCount(_ipAddressDao.findById(addrId).getAllocatedToAccountId(), ResourceType.public_ip); } diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index d0d7f31b9a5..b5c060d8c33 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -48,6 +48,8 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.configuration.dao.ResourceCountDao; import com.cloud.configuration.dao.ResourceLimitDao; import com.cloud.dao.EntityManager; +import com.cloud.dc.VlanVO; +import com.cloud.dc.dao.VlanDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -55,6 +57,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.NetworkDao; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.projects.Project; @@ -143,6 +146,8 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim private ServiceOfferingDao _serviceOfferingDao; @Inject private TemplateDataStoreDao _vmTemplateStoreDao; + @Inject + private VlanDao _vlanDao; protected GenericSearchBuilder templateSizeSearch; @@ -817,7 +822,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim } else if (type == Resource.ResourceType.snapshot) { newCount = _snapshotDao.countSnapshotsForAccount(accountId); } else if (type == Resource.ResourceType.public_ip) { - newCount = _ipAddressDao.countAllocatedIPsForAccount(accountId); + newCount = calculatePublicIpForAccount(accountId); } else if (type == Resource.ResourceType.template) { newCount = _vmTemplateDao.countTemplatesForAccount(accountId); } else if (type == Resource.ResourceType.project) { @@ -909,6 +914,22 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim return totalVolumesSize + totalSnapshotsSize + totalTemplatesSize; } + private long calculatePublicIpForAccount(long accountId) { + Long dedicatedCount = 0L; + Long allocatedCount = 0L; + + List dedicatedVlans = _vlanDao.listDedicatedVlans(accountId); + for (VlanVO dedicatedVlan : dedicatedVlans) { + List ips = _ipAddressDao.listByVlanId(dedicatedVlan.getId()); + dedicatedCount += new Long(ips.size()); + } + allocatedCount = _ipAddressDao.countAllocatedIPsForAccount(accountId); + if (dedicatedCount > allocatedCount) + return dedicatedCount; + else + return allocatedCount; + } + @Override public long getResourceCount(Account account, ResourceType type) { return _resourceCountDao.getResourceCount(account.getId(), ResourceOwnerType.Account, type); From 56e8da7890268aedf4187b66cfbaeba477591435 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Thu, 25 Apr 2013 12:56:38 +0530 Subject: [PATCH 204/303] CLOUDSTACK-2134 updated acl checks for aquiring nic secondary ip --- .../com/cloud/network/NetworkServiceImpl.java | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index d3ef320a981..5f51a30d389 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -610,18 +610,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Invalid network id is given"); } - Network network = _networksDao.findById(networkId); - if (network == null) { - throw new InvalidParameterValueException("Invalid network id is given"); - } - accountId = network.getAccountId(); - domainId = network.getDomainId(); - - // Validate network offering - NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId()); - - // verify permissions - _accountMgr.checkAccess(ipOwner, null, true, network); + Account caller = UserContext.current().getCaller(); //check whether the nic belongs to user vm. NicVO nicVO = _nicDao.findById(nicId); @@ -633,6 +622,25 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("The nic is not belongs to user vm"); } + Nic nic = _nicDao.findById(nicId); + VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId()); + if (vm == null) { + throw new InvalidParameterValueException("There is no vm with the nic"); + } + // verify permissions + _accountMgr.checkAccess(ipOwner, null, true, vm); + + + Network network = _networksDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("Invalid network id is given"); + } + accountId = network.getAccountId(); + domainId = network.getDomainId(); + + // Validate network offering + NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId()); + DataCenter dc = _dcDao.findById(network.getDataCenterId()); Long id = nicVO.getInstanceId(); @@ -649,14 +657,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Allocating guest ip for nic failed"); } } else if (dc.getNetworkType() == NetworkType.Basic || ntwkOff.getGuestType() == Network.GuestType.Shared) { - Account caller = UserContext.current().getCaller(); - long callerUserId = UserContext.current().getCallerUserId(); - _accountMgr.checkAccess(caller, SecurityChecker.AccessType.UseNetwork, false, network); //handle the basic networks here - VirtualMachine vm = _userVmDao.findById(nicVO.getInstanceId()); - if (vm == null) { - throw new InvalidParameterValueException("There is no vm with the nic"); - } VMInstanceVO vmi = (VMInstanceVO)vm; Long podId = vmi.getPodIdToDeployIn(); if (podId == null) { @@ -718,6 +719,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Unable to find ip address by id"); } + VirtualMachine vm = _userVmDao.findById(secIpVO.getVmId()); + if (vm == null) { + throw new InvalidParameterValueException("There is no vm with the nic"); + } + // verify permissions + _accountMgr.checkAccess(caller, null, true, vm); + Network network = _networksDao.findById(secIpVO.getNetworkId()); if (network == null) { @@ -727,9 +735,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { // Validate network offering NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(network.getNetworkOfferingId()); - // verify permissions - _accountMgr.checkAccess(caller, null, true, network); - Long nicId = secIpVO.getNicId(); s_logger.debug("ip id = " + ipAddressId + " nic id = " + nicId); //check is this the last secondary ip for NIC From 21cb2c67b200e0d5dc3bf0af75e44c5d1fe314bc Mon Sep 17 00:00:00 2001 From: Joe Mills Date: Wed, 15 May 2013 17:47:58 +0900 Subject: [PATCH 205/303] Midonet Plugin bugfixes * Updated SQL upgrade scripts to include midonet configs. * Fixed bug where default ICMP allow rule was missing on static NAT creation, keeping VMs from being able to ping the gateway. * Changed the filter in the MidoNetElement callbacks to allow calls when Midonet is configured. Signed-off-by: Hugo Trippaers --- .../cloud/network/element/MidoNetElement.java | 113 +++++++++++------- .../network/guru/MidoNetGuestNetworkGuru.java | 13 +- .../guru/MidoNetPublicNetworkGuru.java | 9 +- .../network/element/MidoNetElementTest.java | 31 +++-- setup/db/db/schema-410to420.sql | 2 + 5 files changed, 107 insertions(+), 61 deletions(-) diff --git a/plugins/network-elements/midonet/src/com/cloud/network/element/MidoNetElement.java b/plugins/network-elements/midonet/src/com/cloud/network/element/MidoNetElement.java index d07fa5624c5..ab6a6def405 100644 --- a/plugins/network-elements/midonet/src/com/cloud/network/element/MidoNetElement.java +++ b/plugins/network-elements/midonet/src/com/cloud/network/element/MidoNetElement.java @@ -36,7 +36,6 @@ import com.cloud.network.NetworkModel; import com.cloud.network.Networks; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PublicIpAddress; -import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.StaticNat; @@ -47,6 +46,8 @@ import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.PluggableService; import com.cloud.utils.net.NetUtils; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; @@ -131,14 +132,14 @@ public class MidoNetElement extends AdapterBase implements @Inject AccountManager _accountMgr; @Inject - NetworkServiceMapDao _ntwkSrvcDao; + AccountDao _accountDao; public void setMidonetApi(MidonetApi api) { this.api = api; } - public void setNtwkSrvcDao(NetworkServiceMapDao ntwkSrvcDao){ - this._ntwkSrvcDao = ntwkSrvcDao; + public void setAccountDao(AccountDao aDao) { + this._accountDao = aDao; } @Override @@ -172,10 +173,13 @@ public class MidoNetElement extends AdapterBase implements } public boolean midoInNetwork(Network network) { - for (String pname : _ntwkSrvcDao.getDistinctProviders(network.getId())) { - if (pname.equals(getProvider().getName())) { - return true; - } + if((network.getTrafficType() == Networks.TrafficType.Public) && + (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Mido)){ + return true; + } + if((network.getTrafficType() == Networks.TrafficType.Guest) && + (network.getBroadcastDomainType() == Networks.BroadcastDomainType.Mido)){ + return true; } return false; } @@ -280,6 +284,11 @@ public class MidoNetElement extends AdapterBase implements post.addRule().type(DtoRule.RevDNAT).flowAction(DtoRule.Accept).create(); } + public String getAccountUuid(Network network) { + AccountVO acc = _accountDao.findById(network.getAccountId()); + return acc.getUuid(); + } + public boolean associatePublicIP(Network network, final List ipAddress) throws ResourceUnavailableException { @@ -316,7 +325,7 @@ public class MidoNetElement extends AdapterBase implements tenantUplink = ports[0]; providerDownlink = ports[1]; - accountIdStr = String.valueOf(network.getAccountId()); + accountIdStr = getAccountUuid(network); boolean isVpc = getIsVpc(network); long id = getRouterId(network, isVpc); routerName = getRouterName(isVpc, id); @@ -611,7 +620,7 @@ public class MidoNetElement extends AdapterBase implements RuleChain preNat = null; RuleChain post = null; - String accountIdStr = String.valueOf(network.getAccountId()); + String accountIdStr = getAccountUuid(network); String networkUUIDStr = String.valueOf(network.getId()); for (StaticNat rule : rules) { @@ -659,7 +668,7 @@ public class MidoNetElement extends AdapterBase implements return false; } if (canHandle(config, Service.Firewall)) { - String accountIdStr = String.valueOf(config.getAccountId()); + String accountIdStr = getAccountUuid(config); String networkUUIDStr = String.valueOf(config.getId()); RuleChain preFilter = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PREFILTER); RuleChain preNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PRENAT); @@ -947,7 +956,7 @@ public class MidoNetElement extends AdapterBase implements return false; } - String accountIdStr = String.valueOf(network.getAccountId()); + String accountIdStr = getAccountUuid(network); String networkUUIDStr = String.valueOf(network.getId()); RuleChain preNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_PRENAT); RuleChain postNat = getChain(accountIdStr, networkUUIDStr, RuleChainCode.TR_POST); @@ -1170,16 +1179,16 @@ public class MidoNetElement extends AdapterBase implements return routerName + "-tenantrouter-" + chain; } - protected RuleChain getChain(String accountID, String routerName, RuleChainCode chainCode){ - return getChain("", accountID, routerName, chainCode); + protected RuleChain getChain(String accountUuid, String routerName, RuleChainCode chainCode){ + return getChain("", accountUuid, routerName, chainCode); } - protected RuleChain getChain(String networkId, String accountID, + protected RuleChain getChain(String networkId, String accountUuid, String routerName, RuleChainCode chainCode){ String chainName = getChainName(networkId, routerName, chainCode); MultivaluedMap findChain = new MultivaluedMapImpl(); - findChain.add("tenant_id", accountID); + findChain.add("tenant_id", accountUuid); ResourceCollection ruleChains = api.getChains(findChain); @@ -1303,7 +1312,7 @@ public class MidoNetElement extends AdapterBase implements String routerName = getRouterName(isVpc, id); RuleChain egressChain = getChain(String.valueOf(network.getId()), - String.valueOf(network.getAccountId()), + getAccountUuid(network), routerName, RuleChainCode.ACL_EGRESS); @@ -1325,7 +1334,7 @@ public class MidoNetElement extends AdapterBase implements String routerName = getRouterName(isVpc, id); RuleChain egressChain = getChain(String.valueOf(network.getId()), - String.valueOf(network.getAccountId()), + getAccountUuid(network), routerName, RuleChainCode.ACL_EGRESS); @@ -1355,6 +1364,14 @@ public class MidoNetElement extends AdapterBase implements .position(pos++) .create(); + // If it is ICMP to the router, accept that + egressChain.addRule().type(DtoRule.Accept) + .nwProto(SimpleFirewallRule.stringToProtocolNumber("icmp")) + .nwDstAddress(network.getGateway()) + .nwDstLength(32) + .position(pos++) + .create(); + // Everything else gets dropped egressChain.addRule() .type(DtoRule.Drop) @@ -1369,7 +1386,7 @@ public class MidoNetElement extends AdapterBase implements boolean isVpc = getIsVpc(network); long id = getRouterId(network, isVpc); String routerName = getRouterName(isVpc, id); - String accountIdStr = String.valueOf(network.getAccountId()); + String accountIdStr = getAccountUuid(network); // Add interior port on bridge side BridgePort bridgePort = netBridge.addInteriorPort().create(); @@ -1406,6 +1423,14 @@ public class MidoNetElement extends AdapterBase implements .position(pos++) .create(); + // If it is ICMP to the router, accept that + inc.addRule().type(DtoRule.Accept) + .nwProto(SimpleFirewallRule.stringToProtocolNumber("icmp")) + .nwDstAddress(network.getGateway()) + .nwDstLength(32) + .position(pos++) + .create(); + // If it is connection tracked, accept that as well inc.addRule().type(DtoRule.Accept) .matchReturnFlow(true) @@ -1449,27 +1474,25 @@ public class MidoNetElement extends AdapterBase implements private Bridge getOrCreateNetworkBridge(Network network){ // Find the single bridge for this network, create if doesn't exist - return getOrCreateNetworkBridge(network.getId(), network.getAccountId()); + return getOrCreateNetworkBridge(network.getId(), getAccountUuid(network)); } - private Bridge getOrCreateNetworkBridge(long networkID, long accountID){ - Bridge netBridge = getNetworkBridge(networkID, accountID); + private Bridge getOrCreateNetworkBridge(long networkID, String accountUuid){ + Bridge netBridge = getNetworkBridge(networkID, accountUuid); if(netBridge == null){ - String accountIdStr = String.valueOf(accountID); String networkUUIDStr = String.valueOf(networkID); - netBridge = api.addBridge().tenantId(accountIdStr).name(networkUUIDStr).create(); + netBridge = api.addBridge().tenantId(accountUuid).name(networkUUIDStr).create(); } return netBridge; } - private Bridge getNetworkBridge(long networkID, long accountID){ + private Bridge getNetworkBridge(long networkID, String accountUuid){ MultivaluedMap qNetBridge = new MultivaluedMapImpl(); - String accountIdStr = String.valueOf(accountID); String networkUUIDStr = String.valueOf(networkID); - qNetBridge.add("tenant_id", accountIdStr); + qNetBridge.add("tenant_id", accountUuid); for (Bridge b : this. api.getBridges(qNetBridge)) { if(b.getName().equals(networkUUIDStr)){ @@ -1497,7 +1520,7 @@ public class MidoNetElement extends AdapterBase implements boolean isVpc = getIsVpc(network); long id = getRouterId(network, isVpc); - return getOrCreateGuestNetworkRouter(id, network.getAccountId(), isVpc); + return getOrCreateGuestNetworkRouter(id, getAccountUuid(network), isVpc); } @@ -1509,29 +1532,28 @@ public class MidoNetElement extends AdapterBase implements } } - protected Router createRouter(long id, long accountID, boolean isVpc) { + protected Router createRouter(long id, String accountUuid, boolean isVpc) { - String accountIdStr = String.valueOf(accountID); String routerName = getRouterName(isVpc, id); //Set up rule chains RuleChain pre = api.addChain() .name(getChainName(routerName, RuleChainCode.TR_PRE)) - .tenantId(accountIdStr) + .tenantId(accountUuid) .create(); RuleChain post = api.addChain() .name(getChainName(routerName, RuleChainCode.TR_POST)) - .tenantId(accountIdStr) + .tenantId(accountUuid) .create(); // Set up NAT and filter chains for pre-routing RuleChain preFilter = api.addChain() .name(getChainName(routerName, RuleChainCode.TR_PREFILTER)) - .tenantId(accountIdStr) + .tenantId(accountUuid) .create(); RuleChain preNat = api.addChain() .name(getChainName(routerName, RuleChainCode.TR_PRENAT)) - .tenantId(accountIdStr) + .tenantId(accountUuid) .create(); // Hook the chains in - first jump to Filter chain, then jump to Nat chain @@ -1545,28 +1567,27 @@ public class MidoNetElement extends AdapterBase implements .create(); return api.addRouter() - .tenantId(accountIdStr) + .tenantId(accountUuid) .name(routerName) .inboundFilterId(pre.getId()) .outboundFilterId(post.getId()) .create(); } - private Router getOrCreateGuestNetworkRouter(long id, long accountID, boolean isVpc) { - Router tenantRouter = getGuestNetworkRouter(id, accountID, isVpc); + private Router getOrCreateGuestNetworkRouter(long id, String accountUuid, boolean isVpc) { + Router tenantRouter = getGuestNetworkRouter(id, accountUuid, isVpc); if(tenantRouter == null){ - tenantRouter = createRouter(id, accountID, isVpc); + tenantRouter = createRouter(id, accountUuid, isVpc); } return tenantRouter; } - private Router getGuestNetworkRouter(long id, long accountID, boolean isVpc){ + private Router getGuestNetworkRouter(long id, String accountUuid, boolean isVpc){ MultivaluedMap qNetRouter = new MultivaluedMapImpl(); - String accountIdStr = String.valueOf(accountID); String routerName = getRouterName(isVpc, id); - qNetRouter.add("tenant_id", accountIdStr); + qNetRouter.add("tenant_id", accountUuid); for (Router router : api.getRouters(qNetRouter)) { if(router.getName().equals(routerName)){ @@ -1613,10 +1634,10 @@ public class MidoNetElement extends AdapterBase implements } private void deleteNetworkBridges(Network network){ - long accountID = network.getAccountId(); + String accountUuid = getAccountUuid(network); long networkID = network.getId(); - Bridge netBridge = getNetworkBridge(networkID, accountID); + Bridge netBridge = getNetworkBridge(networkID, accountUuid); if(netBridge != null){ cleanBridge(netBridge); @@ -1632,11 +1653,11 @@ public class MidoNetElement extends AdapterBase implements } private void deleteGuestNetworkRouters(Network network){ - long accountID = network.getAccountId(); + String accountUuid = getAccountUuid(network); boolean isVpc = getIsVpc(network); long id = getRouterId(network, isVpc); - Router tenantRouter = getGuestNetworkRouter(id, accountID, isVpc); + Router tenantRouter = getGuestNetworkRouter(id, accountUuid, isVpc); // Delete any peer ports corresponding to this router for(Port peerPort : tenantRouter.getPeerPorts((new MultivaluedMapImpl()))){ @@ -1677,7 +1698,7 @@ public class MidoNetElement extends AdapterBase implements } // Remove inbound and outbound filter chains - String accountIdStr = String.valueOf(accountID); + String accountIdStr = String.valueOf(accountUuid); String routerName = getRouterName(isVpc, id); RuleChain pre = api.getChain(tenantRouter.getInboundFilterId()); diff --git a/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetGuestNetworkGuru.java b/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetGuestNetworkGuru.java index 20b74b9e491..d57affc5827 100644 --- a/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetGuestNetworkGuru.java +++ b/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetGuestNetworkGuru.java @@ -30,6 +30,8 @@ import com.cloud.network.*; import com.cloud.network.PhysicalNetwork; import com.cloud.offering.NetworkOffering; import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; import com.cloud.vm.*; import com.midokura.midonet.client.resource.Bridge; import com.cloud.utils.net.NetUtils; @@ -46,12 +48,16 @@ import com.cloud.vm.Nic.ReservationStrategy; import javax.ejb.Local; import java.util.UUID; +import javax.inject.Inject; @Component @Local(value = NetworkGuru.class) public class MidoNetGuestNetworkGuru extends GuestNetworkGuru { private static final Logger s_logger = Logger.getLogger(MidoNetGuestNetworkGuru.class); + @Inject + AccountDao _accountDao; + public MidoNetGuestNetworkGuru() { super(); _isolationMethods = new PhysicalNetwork.IsolationMethod[] { PhysicalNetwork.IsolationMethod.MIDO }; @@ -118,7 +124,8 @@ public class MidoNetGuestNetworkGuru extends GuestNetworkGuru { implemented.setCidr(network.getCidr()); } - String accountIdStr = String.valueOf(network.getAccountId()); + AccountVO acc = _accountDao.findById(network.getAccountId()); + String accountUUIDStr = acc.getUuid(); String routerName = ""; if (network.getVpcId() != null) { routerName = "VPC" + String.valueOf(network.getVpcId()); @@ -126,7 +133,9 @@ public class MidoNetGuestNetworkGuru extends GuestNetworkGuru { routerName = String.valueOf(network.getId()); } - String broadcastUriStr = accountIdStr + "." + String.valueOf(network.getId()) + ":" + routerName; + String broadcastUriStr = accountUUIDStr + "." + + String.valueOf(network.getId()) + + ":" + routerName; implemented.setBroadcastUri(Networks.BroadcastDomainType.Mido.toUri(broadcastUriStr)); s_logger.debug("Broadcast URI set to " + broadcastUriStr); diff --git a/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java b/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java index 7e93edbcd99..1daf0bad040 100644 --- a/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java +++ b/plugins/network-elements/midonet/src/com/cloud/network/guru/MidoNetPublicNetworkGuru.java @@ -34,6 +34,8 @@ import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.IPAddressVO; import com.cloud.vm.*; @@ -50,6 +52,8 @@ public class MidoNetPublicNetworkGuru extends PublicNetworkGuru { // Inject any stuff we need to use (DAOs etc) @Inject NetworkModel _networkModel; + @Inject + AccountDao _accountDao; // Don't need to change traffic type stuff, public is fine @@ -228,9 +232,10 @@ public class MidoNetPublicNetworkGuru extends PublicNetworkGuru { } private URI generateBroadcastUri(Network network){ - String accountIdStr = String.valueOf(network.getAccountId()); + AccountVO acc = _accountDao.findById(network.getAccountId()); + String accountUUIDStr = acc.getUuid(); String networkUUIDStr = String.valueOf(network.getId()); - return Networks.BroadcastDomainType.Mido.toUri(accountIdStr + + return Networks.BroadcastDomainType.Mido.toUri(accountUUIDStr + "." + networkUUIDStr + ":" + diff --git a/plugins/network-elements/midonet/test/com/cloud/network/element/MidoNetElementTest.java b/plugins/network-elements/midonet/test/com/cloud/network/element/MidoNetElementTest.java index aec9c2d9ef9..baf99b908d4 100644 --- a/plugins/network-elements/midonet/test/com/cloud/network/element/MidoNetElementTest.java +++ b/plugins/network-elements/midonet/test/com/cloud/network/element/MidoNetElementTest.java @@ -18,12 +18,13 @@ */ import com.cloud.network.element.MidoNetElement; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; import junit.framework.TestCase; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.*; import com.midokura.midonet.client.MidonetApi; import com.midokura.midonet.client.resource.*; -import com.cloud.network.dao.NetworkServiceMapDao; import com.sun.jersey.core.util.MultivaluedMapImpl; import com.cloud.network.*; import com.cloud.vm.*; @@ -46,10 +47,6 @@ public class MidoNetElementTest extends TestCase { //mockMgmt MidonetApi api = mock(MidonetApi.class, RETURNS_DEEP_STUBS); - ArrayList arr = new ArrayList(); - arr.add("MidoNet"); - NetworkServiceMapDao mockNSMD = mock(NetworkServiceMapDao.class); - when(mockNSMD.getDistinctProviders(anyLong())).thenReturn(arr); //mockDhcpHost DhcpHost mockDhcpHost = mock(DhcpHost.class); @@ -82,6 +79,14 @@ public class MidoNetElementTest extends TestCase { when(mockNetwork.getGateway()).thenReturn("1.2.3.4"); when(mockNetwork.getCidr()).thenReturn("1.2.3.0/24"); when(mockNetwork.getId()).thenReturn((long)2); + when(mockNetwork.getBroadcastDomainType()).thenReturn(Networks.BroadcastDomainType.Mido); + when(mockNetwork.getTrafficType()).thenReturn(Networks.TrafficType.Guest); + + //mockAccountDao + AccountDao mockAccountDao = mock(AccountDao.class); + AccountVO mockAccountVO = mock(AccountVO.class); + when(mockAccountDao.findById(anyLong())).thenReturn(mockAccountVO); + when(mockAccountVO.getUuid()).thenReturn("1"); //mockNic NicProfile mockNic = mock(NicProfile.class); @@ -96,8 +101,8 @@ public class MidoNetElementTest extends TestCase { when(mockVm.getType()).thenReturn(VirtualMachine.Type.User); MidoNetElement elem = new MidoNetElement(); - elem.setNtwkSrvcDao(mockNSMD); elem.setMidonetApi(api); + elem.setAccountDao(mockAccountDao); boolean result = false; try { @@ -119,14 +124,16 @@ public class MidoNetElementTest extends TestCase { public void testImplement() { //mock MidonetApi api = mock(MidonetApi.class, RETURNS_DEEP_STUBS); - ArrayList arr = new ArrayList(); - arr.add("MidoNet"); - NetworkServiceMapDao mockNSMD = mock(NetworkServiceMapDao.class); - when(mockNSMD.getDistinctProviders(anyLong())).thenReturn(arr); + //mockAccountDao + AccountDao mockAccountDao = mock(AccountDao.class); + AccountVO mockAccountVO = mock(AccountVO.class); + when(mockAccountDao.findById(anyLong())).thenReturn(mockAccountVO); + when(mockAccountVO.getUuid()).thenReturn("1"); MidoNetElement elem = new MidoNetElement(); - elem.setNtwkSrvcDao(mockNSMD); + elem.setMidonetApi(api); + elem.setAccountDao(mockAccountDao); //mockRPort RouterPort mockRPort = mock(RouterPort.class); @@ -161,6 +168,8 @@ public class MidoNetElementTest extends TestCase { when(mockNetwork.getGateway()).thenReturn("1.2.3.4"); when(mockNetwork.getCidr()).thenReturn("1.2.3.0/24"); when(mockNetwork.getId()).thenReturn((long)2); + when(mockNetwork.getBroadcastDomainType()).thenReturn(Networks.BroadcastDomainType.Mido); + when(mockNetwork.getTrafficType()).thenReturn(Networks.TrafficType.Public); boolean result = false; try { diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 3b259d8de59..d9ed7a77ba5 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -29,6 +29,8 @@ INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor INSERT IGNORE INTO `cloud`.`hypervisor_capabilities`(hypervisor_type, hypervisor_version, max_guests_limit, security_group_enabled, max_hosts_per_cluster) VALUES ('VMware', '5.1', 128, 0, 32); DELETE FROM `cloud`.`configuration` where name='vmware.percluster.host.max'; INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'AgentManager', 'xen.nics.max', '7', 'Maximum allowed nics for Vms created on Xen'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.apiserver.address', 'http://localhost:8081', 'Specify the address at which the Midonet API server can be contacted (if using Midonet)'); +INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Network', 'DEFAULT', 'management-server', 'midonet.providerrouter.id', 'd7c5e6a3-e2f4-426b-b728-b7ce6a0448e5', 'Specifies the UUID of the Midonet provider router (if using Midonet)'); ALTER TABLE `cloud`.`load_balancer_vm_map` ADD state VARCHAR(40) NULL COMMENT 'service status updated by LB healthcheck manager'; alter table storage_pool change storage_provider_id storage_provider_name varchar(255); From 3fa8fda37c8b9fac1e38b57d28d23917106fe02b Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 15 May 2013 15:54:03 +0100 Subject: [PATCH 206/303] CLOUDSTACK-962: Because of the same reason to this (CLOUDSTACK-685) https://reviews.apache.org/r/11157/ Signed-off-by: Chip Childers --- .../network/router/VirtualNetworkApplianceManagerImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 5de2388742d..b8ad29f6216 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -3957,6 +3957,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); } stats.setCurrentBytesSent(answer.getBytesSent()); + if (! _dailyOrHourly) { + //update agg bytes + stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } _userStatsDao.update(stats.getId(), stats); txn.commit(); } catch (Exception e) { From 20a9d877cf2211abf99c2502601e024a47f22114 Mon Sep 17 00:00:00 2001 From: Marcus Sorensen Date: Wed, 15 May 2013 10:36:22 -0600 Subject: [PATCH 207/303] Summary: Use hypervisor as clock source for system vms BUG-ID: CLOUDSTACK-2492 Bugfix-for: 4.1,master Signed-off-by: Marcus Sorensen 1368635782 -0600 --- .../cloud/hypervisor/kvm/resource/LibvirtComputingResource.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index b3e9be184e2..15d3d583516 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -3146,6 +3146,8 @@ ServerResource { if (vmTO.getOs().startsWith("Windows")) { clock.setClockOffset(ClockDef.ClockOffset.LOCALTIME); clock.setTimer("rtc", "catchup", null); + } else if (vmTO.getType() != VirtualMachine.Type.User) { + clock.setTimer("kvmclock", "catchup", null); } vm.addComp(clock); From 9240095d922d11a869c56920cb4a8b74ebb6e04e Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Wed, 15 May 2013 10:32:32 -0700 Subject: [PATCH 208/303] Fixed applyLbRules for Netscaler. --- .../src/com/cloud/network/element/NetscalerElement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java index 60d6674fdb4..cc2bcc17a43 100644 --- a/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java +++ b/plugins/network-elements/netscaler/src/com/cloud/network/element/NetscalerElement.java @@ -240,7 +240,7 @@ public class NetscalerElement extends ExternalLoadBalancerDeviceManagerImpl impl return false; } - if (canHandleLbRules(rules)) { + if (!canHandleLbRules(rules)) { return false; } From 3bf10505b83d65040c1ce7b163a72413826dd71d Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Wed, 15 May 2013 11:01:43 -0700 Subject: [PATCH 209/303] CLOUDSTACK-747: internalLb in VPC - UI - create tier dialog - only one tier is allowed to have PublicLb in a VPC. --- ui/scripts/sharedFunctions.js | 34 +++++++++++----------------------- ui/scripts/vpc.js | 9 +++++---- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index a01840637e3..035299059c2 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -122,34 +122,22 @@ function createURL(apiName, options) { return urlString; } -/* -function fromdb(val) { - return sanitizeXSS(noNull(val)); -} -*/ - function todb(val) { return encodeURIComponent(val); } -/* -function noNull(val) { - if(val == null) - return ""; - else - return val; -} -*/ +//LB provider map +var lbProviderMap = { + "publicLb": { + "non-vpc": ["VirtualRouter", "Netscaler", "F5"], + "vpc": ["VpcVirtualRouter", "Netscaler"] + }, + "internalLb": { + "non-vpc": [], + "vpc": ["InternalLbVm"] + } +}; -/* -function sanitizeXSS(val) { // Prevent cross-site-script(XSS) attack - if(val == null || typeof(val) != "string") - return val; - val = val.replace(//g, ">"); //replace > whose unicode is \u003e - return unescape(val); -} -*/ // Role Functions function isAdmin() { diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js index 0c4a446485b..4890dcc6ee9 100644 --- a/ui/scripts/vpc.js +++ b/ui/scripts/vpc.js @@ -2344,15 +2344,16 @@ var items; if(networkSupportingLbExists == true) { items = $.grep(networkOfferings, function(networkOffering) { - var includingLbService = false; + var includingPublicLbService = false; $(networkOffering.service).each(function(){ var thisService = this; - if(thisService.name == "Lb") { - includingLbService = true; + //only one tier is allowed to have PublicLb provider in a VPC + if(thisService.name == "Lb" && lbProviderMap.publicLb.vpc.indexOf(thisService.provider[0].name) != -1) { + includingPublicLbService = true; return false; //break $.each() loop } }); - return !includingLbService; + return !includingPublicLbService; }); } else { From c476d7866ec648c648adbe30ddae07fb804e5548 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 15 May 2013 19:41:21 -0700 Subject: [PATCH 210/303] CLOUDSTACK-2482: fix create volume from snapshot --- .../apache/cloudstack/storage/volume/VolumeServiceImpl.java | 4 ++-- .../internallbelement/ElementChildTestConfiguration.java | 2 +- .../cloudstack/internallbvmmgr/LbChildTestConfiguration.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 48160f41702..ba4693cbfbe 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -507,7 +507,7 @@ public class VolumeServiceImpl implements VolumeService { try { DataObject volumeOnStore = store.create(volume); - volume.processEvent(Event.CreateOnlyRequested); + volumeOnStore.processEvent(Event.CreateOnlyRequested); snapshot.processEvent(Event.CopyingRequested); CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, volume, store, volumeOnStore, future, snapshot); @@ -528,7 +528,7 @@ public class VolumeServiceImpl implements VolumeService { protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { CopyCommandResult result = callback.getResult(); - VolumeInfo volume = (VolumeInfo)context.vo; + VolumeInfo volume = (VolumeInfo)context.templateOnStore; SnapshotInfo snapshot = context.snapshot; VolumeApiResult apiResult = new VolumeApiResult(volume); Event event = null; diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java index 8a67e84f951..bddf713e3a8 100644 --- a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbelement/ElementChildTestConfiguration.java @@ -46,7 +46,7 @@ import com.cloud.vm.dao.DomainRouterDao; @Configuration @ComponentScan( basePackageClasses={ - NetUtils.class, + NetUtils.class }, includeFilters={@Filter(value=ElementChildTestConfiguration.Library.class, type=FilterType.CUSTOM)}, useDefaultFilters=false diff --git a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java index 74e54b23295..4f03b27b013 100644 --- a/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java +++ b/plugins/network-elements/internal-loadbalancer/test/org/apache/cloudstack/internallbvmmgr/LbChildTestConfiguration.java @@ -56,7 +56,7 @@ import com.cloud.user.dao.AccountDao; @Configuration @ComponentScan( basePackageClasses={ - NetUtils.class, + NetUtils.class }, includeFilters={@Filter(value=LbChildTestConfiguration.Library.class, type=FilterType.CUSTOM)}, useDefaultFilters=false From d5ab59614af70be8cb89d3d0400521f9f2a3ee19 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 16 May 2013 13:04:00 -0700 Subject: [PATCH 211/303] CLOUDSTACK-2505: object_store - UI - infrastructure menu - add secondary storage- S3 - not pass details[i] info when corresponding field is empty. --- ui/scripts/system.js | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index ceee26c6c7d..4c95b0b3b8c 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -11186,27 +11186,43 @@ }); } else if(args.data.provider == 'S3') { + var data = { + provider: args.data.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.bucket, + 'details[3].key': 'usehttps', + 'details[3].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false') + }; + debugger; + var index = 4; + if(args.data.endpoint != null && args.data.endpoint.length > 0){ + data['details[' + index.toString() + '].key'] = 'endpoint'; + data['details[' + index.toString() + '].value'] = args.data.endpoint; + index++; + } + if(args.data.connectiontimeout != null && args.data.connectiontimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'connectiontimeout'; + data['details[' + index.toString() + '].value'] = args.data.connectiontimeout; + index++; + } + if(args.data.maxerrorretry != null && args.data.maxerrorretry.length > 0){ + data['details[' + index.toString() + '].key'] = 'maxerrorretry'; + data['details[' + index.toString() + '].value'] = args.data.maxerrorretry; + index++; + } + if(args.data.sockettimeout != null && args.data.sockettimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'sockettimeout'; + data['details[' + index.toString() + '].value'] = args.data.sockettimeout; + index++; + } + $.ajax({ url: createURL('addImageStore'), - data: { - provider: args.data.provider, - 'details[0].key': 'accesskey', - 'details[0].value': args.data.accesskey, - 'details[1].key': 'secretkey', - 'details[1].value': args.data.secretkey, - 'details[2].key': 'bucket', - 'details[2].value': args.data.bucket, - 'details[3].key': 'endpoint', - 'details[3].value': args.data.endpoint, - 'details[4].key': 'usehttps', - 'details[4].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false'), - 'details[5].key': 'connectiontimeout', - 'details[5].value': args.data.connectiontimeout, - 'details[6].key': 'maxerrorretry', - 'details[6].value': args.data.maxerrorretry, - 'details[7].key': 'sockettimeout', - 'details[7].value': args.data.sockettimeout - }, + data: data, success: function(json) { havingS3 = true; var item = json.addimagestoreresponse.secondarystorage; From 47aeda9893ff218fe6f52467d3eb762d9417f445 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 16 May 2013 13:13:29 -0700 Subject: [PATCH 212/303] CLOUDSTACK-2505: object_store - UI - infrastructure menu - add secondary storage- Swift - not pass details[i] info when corresponding field is empty. --- ui/scripts/system.js | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 4c95b0b3b8c..5cb59a37ce6 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -11196,8 +11196,7 @@ 'details[2].value': args.data.bucket, 'details[3].key': 'usehttps', 'details[3].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false') - }; - debugger; + }; var index = 4; if(args.data.endpoint != null && args.data.endpoint.length > 0){ data['details[' + index.toString() + '].key'] = 'endpoint'; @@ -11260,18 +11259,29 @@ } } else if(args.data.provider == 'Swift') { + var data = { + provider: args.data.provider, + url: args.data.url + }; + var index = 0; + if(args.data.account != null && args.data.account.length > 0){ + data['details[' + index.toString() + '].key'] = 'account'; + data['details[' + index.toString() + '].value'] = args.data.account; + index++; + } + if(args.data.username != null && args.data.username.length > 0){ + data['details[' + index.toString() + '].key'] = 'username'; + data['details[' + index.toString() + '].value'] = args.data.username; + index++; + } + if(args.data.key != null && args.data.key.length > 0){ + data['details[' + index.toString() + '].key'] = 'key'; + data['details[' + index.toString() + '].value'] = args.data.key; + index++; + } $.ajax({ url: createURL('addImageStore'), - data: { - provider: args.data.provider, - url: args.data.url, - 'details[0].key': 'account', - 'details[0].value': args.data.account, - 'details[1].key': 'username', - 'details[1].value': args.data.username, - 'details[2].key': 'key', - 'details[2].value': args.data.key - }, + data: data, success: function(json) { havingSwift = true; var item = json.addimagestoreresponse.secondarystorage; From 44adba06f490e6a76a643a22ca9739b4e38d5925 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 16 May 2013 13:53:57 -0700 Subject: [PATCH 213/303] CLOUDSTACK-2505: object_store - UI - zone wizard - add secondary storage- S3, Swift - not pass details[i] info when corresponding field is empty. --- ui/scripts/zoneWizard.js | 85 ++++++++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 30 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 137fe453f8c..19e728db8f9 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -3692,27 +3692,41 @@ }); } else if(args.data.secondaryStorage.provider == 'S3') { + var data = { + provider: args.data.secondaryStorage.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.secondaryStorage.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secondaryStorage.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.secondaryStorage.bucket, + 'details[3].key': 'usehttps', + 'details[3].value': (args.data.secondaryStorage.usehttps != null && args.data.secondaryStorage.usehttps == 'on' ? 'true' : 'false') + }; + var index = 4; + if(args.data.secondaryStorage.endpoint != null && args.data.secondaryStorage.endpoint.length > 0){ + data['details[' + index.toString() + '].key'] = 'endpoint'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.endpoint; + index++; + } + if(args.data.secondaryStorage.connectiontimeout != null && args.data.secondaryStorage.connectiontimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'connectiontimeout'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.connectiontimeout; + index++; + } + if(args.data.secondaryStorage.maxerrorretry != null && args.data.secondaryStorage.maxerrorretry.length > 0){ + data['details[' + index.toString() + '].key'] = 'maxerrorretry'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.maxerrorretry; + index++; + } + if(args.data.secondaryStorage.sockettimeout != null && args.data.secondaryStorage.sockettimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'sockettimeout'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.sockettimeout; + index++; + } $.ajax({ url: createURL('addImageStore'), - data: { - provider: args.data.secondaryStorage.provider, - 'details[0].key': 'accesskey', - 'details[0].value': args.data.secondaryStorage.accesskey, - 'details[1].key': 'secretkey', - 'details[1].value': args.data.secondaryStorage.secretkey, - 'details[2].key': 'bucket', - 'details[2].value': args.data.secondaryStorage.bucket, - 'details[3].key': 'endpoint', - 'details[3].value': args.data.secondaryStorage.endpoint, - 'details[4].key': 'usehttps', - 'details[4].value': (args.data.secondaryStorage.usehttps != null && args.data.secondaryStorage.usehttps == 'on' ? 'true' : 'false'), - 'details[5].key': 'connectiontimeout', - 'details[5].value': args.data.secondaryStorage.connectiontimeout, - 'details[6].key': 'maxerrorretry', - 'details[6].value': args.data.secondaryStorage.maxerrorretry, - 'details[7].key': 'sockettimeout', - 'details[7].value': args.data.secondaryStorage.sockettimeout - }, + data: data, success: function(json) { complete({ data: $.extend(args.data, { @@ -3751,19 +3765,30 @@ }); } } - else if(args.data.secondaryStorage.provider == 'Swift') { + else if(args.data.secondaryStorage.provider == 'Swift') { + var data = { + provider: args.data.secondaryStorage.provider, + url: args.data.secondaryStorage.url + }; + var index = 0; + if(args.data.secondaryStorage.account != null && args.data.secondaryStorage.account.length > 0){ + data['details[' + index.toString() + '].key'] = 'account'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.account; + index++; + } + if(args.data.secondaryStorage.username != null && args.data.secondaryStorage.username.length > 0){ + data['details[' + index.toString() + '].key'] = 'username'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.username; + index++; + } + if(args.data.secondaryStorage.key != null && args.data.secondaryStorage.key.length > 0){ + data['details[' + index.toString() + '].key'] = 'key'; + data['details[' + index.toString() + '].value'] = args.data.secondaryStorage.key; + index++; + } $.ajax({ url: createURL('addImageStore'), - data: { - provider: args.data.secondaryStorage.provider, - url: args.data.secondaryStorage.url, - 'details[0].key': 'account', - 'details[0].value': args.data.secondaryStorage.account, - 'details[1].key': 'username', - 'details[1].value': args.data.secondaryStorage.username, - 'details[2].key': 'key', - 'details[2].value': args.data.secondaryStorage.key - }, + data: data, success: function(json) { complete({ data: $.extend(args.data, { From cd318661d2f60ed218f5c1fa7b316b9228148216 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 16 May 2013 13:54:32 -0700 Subject: [PATCH 214/303] CLOUDSTACK-2505: object_store - UI - infrastructure menu - secondary storages - add URL, Provider, Scope, Details to detailView. --- ui/scripts/system.js | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 5cb59a37ce6..527d80b16c3 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -10878,15 +10878,8 @@ section: 'seconary-storage', fields: { name: { label: 'label.name' }, - created: { label: 'label.created', converter: cloudStack.converters.toLocalDate }, - resourcestate: { - label: 'label.state', - indicator: { - 'Enabled': 'on', - 'Disabled': 'off', - 'Destroyed': 'off' - } - } + url: { label: 'label.url' }, + providername: { label: 'Provider' } }, dataProvider: function(args) { @@ -11349,10 +11342,27 @@ { name: { label: 'label.name' } }, - { - id: { label: 'label.id' }, + { + url: { label: 'label.url' }, + providername: { label: 'Provider' }, + scope: { label: 'label.scope' }, zonename: { label: 'label.zone' }, - created: { label: 'label.created', converter: cloudStack.converters.toLocalDate } + details: { + label: 'label.details', + converter: function(array1) { + var string1 = ''; + if(array1 != null) { + for(var i = 0; i < array1.length; i++) { + if(i > 0) + string1 += ', '; + + string1 += array1[i].name + ': ' + array1[i].value; + } + } + return string1; + } + }, + id: { label: 'label.id' } } ], From 389d7c1fa075441b6c6471b81dedbd8e8720fe88 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 16 May 2013 14:33:36 -0700 Subject: [PATCH 215/303] if object is already stored in cache store, don't download again --- .../storage/cache/manager/StorageCacheManagerImpl.java | 10 ++++++++++ .../src/com/cloud/ovm/hypervisor/OvmResourceBase.java | 1 - test/integration/smoke/test_volumes.py | 9 +++------ 3 files changed, 13 insertions(+), 7 deletions(-) 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 index 8fb898e12e1..c76e67b8c81 100644 --- 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 @@ -28,7 +28,9 @@ import javax.naming.ConfigurationException; 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; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; 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.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; @@ -51,6 +53,8 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { List storageCacheAllocator; @Inject DataMotionService dataMotionSvr; + @Inject + ObjectInDataStoreManager objectInStoreMgr; @Override public DataStore getCacheStorage(Scope scope) { @@ -133,6 +137,12 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { @Override public DataObject createCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); + DataObjectInStore obj = objectInStoreMgr.findObject(data, cacheStore); + if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready) { + s_logger.debug("there is already one in the cache store"); + return objectInStoreMgr.get(data, cacheStore); + } + //TODO: consider multiple thread to create DataObject objOnCacheStore = cacheStore.create(data); diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index 61ac54e5523..59ba001d04c 100755 --- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -131,7 +131,6 @@ import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; import com.trilead.ssh2.SCPClient; -import com.xensource.xenapi.Types.XenAPIException; public class OvmResourceBase implements ServerResource, HypervisorResource { private static final Logger s_logger = Logger.getLogger(OvmResourceBase.class); diff --git a/test/integration/smoke/test_volumes.py b/test/integration/smoke/test_volumes.py index 4bf8203e74c..f29410d0b29 100644 --- a/test/integration/smoke/test_volumes.py +++ b/test/integration/smoke/test_volumes.py @@ -19,6 +19,7 @@ #Import Local Modules import marvin from marvin.cloudstackTestCase import * +from marvin.cloudstackException import * from marvin.cloudstackAPI import * from marvin.remoteSSHClient import remoteSSHClient from marvin.integration.lib.utils import * @@ -449,12 +450,8 @@ class TestVolumes(cloudstackTestCase): cmd.id = self.volume.id #Proper exception should be raised; deleting attach VM is not allowed #with self.assertRaises(Exception): - result = self.apiClient.deleteVolume(cmd) - self.assertEqual( - result, - None, - "Check for delete download error while volume is attached" - ) + with self.assertRaises(cloudstackAPIException): + self.apiClient.deleteVolume(cmd) @attr(tags = ["advanced", "advancedns", "smoke"]) def test_05_detach_volume(self): From 84607c1e53450c6f5a41ed16fba9e006fb3edf6b Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 17 May 2013 17:49:40 -0700 Subject: [PATCH 216/303] Fix CLOUDSTACK-2537: Use mount.parent configured value to mount NFS cache on MS to avoid permission issue. --- .../resource/LocalNfsSecondaryStorageResource.java | 14 +++++++++++++- .../resource/NfsSecondaryStorageResource.java | 6 ++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java index 7322a81353c..02ff8bc1261 100644 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalNfsSecondaryStorageResource.java @@ -44,6 +44,8 @@ import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDaoImpl; import com.cloud.storage.JavaStorageLayer; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; @@ -57,13 +59,20 @@ import com.cloud.utils.script.Script; @Component public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { - private static final Logger s_logger = Logger.getLogger(NfsSecondaryStorageResource.class); + private static final Logger s_logger = Logger.getLogger(LocalNfsSecondaryStorageResource.class); public LocalNfsSecondaryStorageResource() { this._dlMgr = new DownloadManagerImpl(); ((DownloadManagerImpl) _dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); _storage = new JavaStorageLayer(); this._inSystemVM = false; + // get mount parent folder configured in global setting, if set, this will overwrite _parent in NfsSecondaryStorageResource to work + // around permission issue for default /mnt folder + ConfigurationDaoImpl configDao = new ConfigurationDaoImpl(); + String mountParent = configDao.getValue(Config.MountParent.key()); + if (mountParent != null) { + _parent = mountParent + File.separator + "secStorage"; + } } @Override @@ -171,6 +180,7 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc res.addAll(parser.getPaths()); for (String s : res) { if (s.contains(root)) { + s_logger.debug("mount point " + root + " already exists"); return root; } } @@ -194,6 +204,7 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc file.delete(); return null; } + s_logger.debug("Successfully mount " + nfsPath); // Change permissions for the mountpoint script = new Script(true, "chmod", _timeout, s_logger); @@ -203,6 +214,7 @@ public class LocalNfsSecondaryStorageResource extends NfsSecondaryStorageResourc s_logger.warn("Unable to set permissions for " + root + " due to " + result); return null; } + s_logger.debug("Successfully set 777 permission for " + root); // XXX: Adding the check for creation of snapshots dir here. Might have // to move it somewhere more logical later. diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 1125d7fdb50..24b2e0b8c2d 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -236,11 +236,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S downloadDirectory.mkdirs(); if (!downloadDirectory.exists()) { - final String errMsg = format("Unable to create directory " + "download directory %1$s for download from S3.", - downloadDirectory.getName()); + final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache."; s_logger.error(errMsg); return new CopyCmdAnswer(errMsg); } + else{ + s_logger.debug("Directory " + downloadPath + " already exists"); + } List files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() { @Override From 255d08ae7c57b23fe4f461459339600b879d8c16 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 12:06:36 -0700 Subject: [PATCH 217/303] Fix CLOUDSTACK-2586: ExtractTemplate for S3 template should give URL directly from S3. --- .../cloud/template/TemplateManagerImpl.java | 39 ++++++++++++++++--- utils/src/com/cloud/utils/S3Utils.java | 10 +++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 9c7069a80d2..c78377309de 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -78,6 +78,7 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.AttachIsoCommand; @@ -87,6 +88,7 @@ import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.S3TO; import com.cloud.api.ApiDBUtils; import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.api.query.vo.UserVmJoinVO; @@ -110,6 +112,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; +import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor; @@ -179,6 +182,7 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.EnumUtils; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.S3Utils; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.NamedThreadFactory; @@ -456,9 +460,32 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); } - if ( tmpltStore.getProviderName().equalsIgnoreCase("S3") || tmpltStore.getProviderName().equalsIgnoreCase("Swift")){ - // for S3 and Swift, no need to do anything, just return template url for extract template, here we use "-1" to indicate these case - return new Pair(null, tmpltStoreRef.getInstallPath()); + if (tmpltStore.getProviderName().equalsIgnoreCase("Swift")){ + throw new UnsupportedServiceException("ExtractTemplate is not yet supported for Swift image store provider"); + } + + if ( tmpltStore.getProviderName().equalsIgnoreCase("S3")){ + // for S3, no need to do anything, just return template url for extract template. but we need to set object acl as public_read to + // make the url accessible + S3TO s3 = (S3TO)tmpltStore.getTO(); + String key = tmpltStoreRef.getLocalDownloadPath(); + try{ + S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); + } + catch (Exception ex){ + s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); + throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); + } + // construct the url from s3 + StringBuffer s3url = new StringBuffer(); + s3url.append(s3.isHttps() ? "https://" : "http://"); + s3url.append(s3.getEndPoint()); + s3url.append("/"); + s3url.append(s3.getBucketName()); + s3url.append("/"); + s3url.append(key); + + return new Pair(null, s3url.toString()); } @@ -1049,7 +1076,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.warn("ISO: " + isoId + " does not exist"); return false; } - + String vmName = vm.getInstanceName(); HostVO host = _hostDao.findById(vm.getHostId()); @@ -1057,7 +1084,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.warn("Host: " + vm.getHostId() + " does not exist"); return false; } - + DataTO isoTO = tmplt.getTO(); DiskTO disk = new DiskTO(isoTO, null, Volume.Type.ISO); Command cmd = null; @@ -1125,7 +1152,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template.getFormat() != ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid iso."); } - + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. if (!userVmUsingIso.isEmpty()) { diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index 8199b084e72..711d1cb9fc4 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -52,6 +52,7 @@ import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.Bucket; +import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.GetObjectRequest; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; @@ -167,6 +168,15 @@ public final class S3Utils { } + public static void setObjectAcl(final ClientOptions clientOptions, final String bucketName, final String key, + final CannedAccessControlList acl) { + + assert clientOptions != null; + assert acl != null; + + acquireClient(clientOptions).setObjectAcl(bucketName, key, acl); + + } // Note that whenever S3Object is returned, client code needs to close the internal stream to avoid resource leak. public static S3Object getObject(final ClientOptions clientOptions, From ef541a2a7bc0aba35009fea38644ae1cb15ad946 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 13:39:43 -0700 Subject: [PATCH 218/303] Fix CLOUDSTACK-2538: Add name as an optional parameter for addImageStore api. --- .../api/command/admin/storage/AddImageStoreCmd.java | 8 ++++++++ .../lifecycle/CloudStackImageStoreLifeCycleImpl.java | 6 +++++- .../datastore/lifecycle/S3ImageStoreLifeCycleImpl.java | 3 ++- .../datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java | 2 ++ server/src/com/cloud/storage/StorageManagerImpl.java | 2 +- 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java index 08112f0aab0..1e383c9647b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/storage/AddImageStoreCmd.java @@ -44,6 +44,9 @@ public class AddImageStoreCmd extends BaseCmd { //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// + @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name for the image store") + private String name; + @Parameter(name=ApiConstants.URL, type=CommandType.STRING, description="the URL for the image store") private String url; @@ -65,10 +68,15 @@ public class AddImageStoreCmd extends BaseCmd { /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// + public String getUrl() { return url; } + public String getName() { + return name; + } + public Long getZoneId() { return zoneId; } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java index 84df7122268..d550f0b3b48 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java @@ -80,6 +80,10 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); + String name = (String)dsInfos.get("name"); + if ( name == null ){ + name = url; + } String providerName = (String)dsInfos.get("providerName"); DataStoreRole role =(DataStoreRole) dsInfos.get("role"); Map details = (Map)dsInfos.get("details"); @@ -111,7 +115,7 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { Map imageStoreParameters = new HashMap(); - imageStoreParameters.put("name", url); + imageStoreParameters.put("name", name); imageStoreParameters.put("zoneId", dcId); imageStoreParameters.put("url", url); imageStoreParameters.put("protocol", uri.getScheme().toLowerCase()); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java index 1b5e2d57344..4ea97e57bfc 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -84,6 +84,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); + String name = (String)dsInfos.get("name"); String providerName = (String)dsInfos.get("providerName"); ScopeType scope = (ScopeType)dsInfos.get("scope"); DataStoreRole role =(DataStoreRole) dsInfos.get("role"); @@ -102,7 +103,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { */ Map imageStoreParameters = new HashMap(); - imageStoreParameters.put("name", url); + imageStoreParameters.put("name", name); imageStoreParameters.put("zoneId", dcId); imageStoreParameters.put("url", url); String protocol = "http"; diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java index 411e052440f..3fc68a1e8fe 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -80,6 +80,7 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); + String name = (String)dsInfos.get("name"); ScopeType scope = (ScopeType)dsInfos.get("scope"); String providerName = (String)dsInfos.get("providerName"); DataStoreRole role =(DataStoreRole) dsInfos.get("role"); @@ -90,6 +91,7 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { // just need to insert an entry in DB Map imageStoreParameters = new HashMap(); + imageStoreParameters.put("name", name); imageStoreParameters.put("zoneId", dcId); imageStoreParameters.put("url", url); imageStoreParameters.put("protocol", "http"); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 504cdc64948..ba6b3434ad6 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1892,7 +1892,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C Map params = new HashMap(); params.put("zoneId", dcId); params.put("url", cmd.getUrl()); - params.put("name", cmd.getUrl()); + params.put("name", cmd.getName()); params.put("details", details); params.put("scope", scopeType); params.put("providerName", storeProvider.getName()); From 565bdfb27b0e5a151d7acbc6471c676bb1e2ec25 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 16:21:45 -0700 Subject: [PATCH 219/303] Fix CLOUDSTACK-2525: clean up db entries in vm_template and template_store_ref in case of template creation failure. --- .../storage/datastore/db/TemplateDataStoreDao.java | 2 ++ .../storage/image/db/TemplateDataStoreDaoImpl.java | 9 +++++++++ server/src/com/cloud/template/TemplateManagerImpl.java | 2 ++ 3 files changed, 13 insertions(+) diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index dbb8dbdbc6d..b83c590266f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -37,6 +37,8 @@ public interface TemplateDataStoreDao extends GenericDao listByTemplateStore(long templateId, long storeId); List listByTemplateStoreStatus(long templateId, long storeId, State... states); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index 345098c6898..d41733d6d29 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -182,6 +182,15 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = templateSearch.create(); + sc.setParameters("template_id", templateId); + Transaction txn = Transaction.currentTxn(); + txn.start(); + expunge(sc); + txn.commit(); + } @Override public List listByTemplateStore(long templateId, long storeId) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c78377309de..dca892f0037 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1456,6 +1456,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (privateTemplate == null) { Transaction txn = Transaction.currentTxn(); txn.start(); + // Remove the template_store_ref record first, otherwise, we cannot remove the template record due to FK constraints + this._tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); // Remove the template record this._tmpltDao.expunge(templateId); From b9378ae5ad6e1b92d4954ec3228853e1a9b08e40 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 16:44:31 -0700 Subject: [PATCH 220/303] Fix cache storage selection in case of zone scope id passed is null. --- .../cloudstack/storage/image/db/ImageStoreDaoImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index e6a0e06a8bb..70316b9ee1c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -95,8 +95,10 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem public List findImageCacheByScope(ZoneScope scope) { SearchCriteria sc = createSearchCriteria(); sc.addAnd("role", SearchCriteria.Op.EQ, DataStoreRole.ImageCache); - sc.addAnd("scope", SearchCriteria.Op.EQ, ScopeType.ZONE); - sc.addAnd("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + if (scope.getScopeId() != null) { + sc.addAnd("scope", SearchCriteria.Op.EQ, ScopeType.ZONE); + sc.addAnd("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); + } return listBy(sc); } From 5be7f7ddb113b09a062a7e9fd668002c944ad800 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 21:25:59 -0700 Subject: [PATCH 221/303] VolumeObject.processEvent for ImageCache should only change state in volume_store_ref, not volume table itself. --- .../org/apache/cloudstack/storage/volume/VolumeObject.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 77bce63a9ad..e1f018055b5 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -186,6 +186,10 @@ public class VolumeObject implements VolumeInfo { } try { Volume.Event volEvent = null; + if ( this.dataStore.getRole() == DataStoreRole.ImageCache){ + ojbectInStoreMgr.update(this, event); + return; + } if (this.dataStore.getRole() == DataStoreRole.Image) { ojbectInStoreMgr.update(this, event); if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { From 93be5ada9bab5ad0495af5b736a53f7eb7c9a49c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 21:26:33 -0700 Subject: [PATCH 222/303] Correct wrong provider name in invoking old addSecondaryStorageCmd. --- .../api/command/admin/host/AddSecondaryStorageCmd.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java index d663575895d..14725d3499b 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/AddSecondaryStorageCmd.java @@ -81,7 +81,7 @@ public class AddSecondaryStorageCmd extends BaseCmd { AddImageStoreCmd cmd = new AddImageStoreCmd(); cmd.setUrl(this.getUrl()); cmd.setZoneId(this.getZoneId()); - cmd.setProviderName("CloudStack ImageStore Provider"); + cmd.setProviderName("NFS"); try{ ImageStore result = _storageService.discoverImageStore(cmd); From 2f6d94462e4b78e67fcc59c1c99b0f398fba98a8 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 20 May 2013 21:36:50 -0700 Subject: [PATCH 223/303] Support multiple secondary storages for backup snapshot. --- .../storage/snapshot/SnapshotServiceImpl.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index fa6d558f532..25c283a57e3 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -163,7 +163,7 @@ public class SnapshotServiceImpl implements SnapshotService { } catch (Exception e) { s_logger.debug("Failed to update snapshot state due to " + e.getMessage()); } - + snapResult.setResult(result.getResult()); future.complete(snapResult); return null; @@ -186,12 +186,12 @@ public class SnapshotServiceImpl implements SnapshotService { return null; } - + @Override public SnapshotResult takeSnapshot(SnapshotInfo snap) { SnapshotObject snapshot = (SnapshotObject)snap; - + SnapshotObject snapshotOnPrimary = null; try { snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot); @@ -268,13 +268,11 @@ public class SnapshotServiceImpl implements SnapshotService { snapObj.processEvent(Snapshot.Event.BackupToSecondary); - ZoneScope scope = new ZoneScope(snapshot.getDataCenterId()); - List stores = this.dataStoreMgr.getImageStoresByScope(scope); - if (stores.size() != 1) { - throw new CloudRuntimeException("find out more than one image stores"); + DataStore imageStore = this.dataStoreMgr.getImageStore(snapshot.getDataCenterId()); + if (imageStore == null) { + throw new CloudRuntimeException("can not find an image stores"); } - DataStore imageStore = stores.get(0); SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot); snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); @@ -431,7 +429,7 @@ public class SnapshotServiceImpl implements SnapshotService { } catch (ExecutionException e) { s_logger.debug("delete snapshot is failed: " + e.toString()); } - + return false; } From 8f549db518ed94b25dc17d42f3a25907aad0d66e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 12:00:04 -0700 Subject: [PATCH 224/303] Clean up entries in template_store_ref, volume_store_ref and snapshot_store_ref in case of operation failure. --- .../api/storage/StorageCacheManager.java | 2 +- .../datastore/db/SnapshotDataStoreVO.java | 2 - .../motion/AncientDataMotionStrategy.java | 34 +-- .../storage/image/store/TemplateObject.java | 18 +- .../storage/snapshot/SnapshotObject.java | 230 +++++++++--------- .../storage/volume/VolumeObject.java | 78 +++--- 6 files changed, 200 insertions(+), 164 deletions(-) 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 index 0aa30d39b1d..917a5376526 100644 --- 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 @@ -28,5 +28,5 @@ public interface StorageCacheManager { * @return */ DataObject getCacheObject(DataObject data, Scope scope); - DataObject deleteCacheObject(DataObject data); + boolean deleteCacheObject(DataObject data); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index 0085086e437..edb23d034f9 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -81,8 +81,6 @@ public class SnapshotDataStoreVO implements StateObject Date: Tue, 21 May 2013 12:00:59 -0700 Subject: [PATCH 225/303] Clean up template_zone_ref entries in case of create template failure. --- .../cloud/storage/dao/VMTemplateZoneDao.java | 8 +++-- .../storage/dao/VMTemplateZoneDaoImpl.java | 29 ++++++++++++++----- .../manager/StorageCacheManagerImpl.java | 11 ++++--- .../cloud/template/TemplateManagerImpl.java | 5 ++-- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java index bb3aa010116..27e05c92e3d 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java @@ -23,11 +23,13 @@ import com.cloud.utils.db.GenericDao; public interface VMTemplateZoneDao extends GenericDao { public List listByZoneId(long id); - + public List listByTemplateId(long templateId); - + public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId); - + public List listByZoneTemplate(Long zoneId, long templateId); + public void deletePrimaryRecordsForTemplate(long templateId); + } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java index 916e0aceb2c..27b554cdb8a 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java @@ -20,6 +20,7 @@ import java.util.List; import javax.ejb.Local; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -27,32 +28,33 @@ import com.cloud.storage.VMTemplateZoneVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.Transaction; @Component @Local(value={VMTemplateZoneDao.class}) public class VMTemplateZoneDaoImpl extends GenericDaoBase implements VMTemplateZoneDao { public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName()); - + protected final SearchBuilder ZoneSearch; protected final SearchBuilder TemplateSearch; protected final SearchBuilder ZoneTemplateSearch; - - + + public VMTemplateZoneDaoImpl () { ZoneSearch = createSearchBuilder(); ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); ZoneSearch.done(); - + TemplateSearch = createSearchBuilder(); TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); TemplateSearch.done(); - + ZoneTemplateSearch = createSearchBuilder(); ZoneTemplateSearch.and("zone_id", ZoneTemplateSearch.entity().getZoneId(), SearchCriteria.Op.EQ); ZoneTemplateSearch.and("template_id", ZoneTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); ZoneTemplateSearch.done(); } - + @Override public List listByZoneId(long id) { @@ -84,6 +86,19 @@ public class VMTemplateZoneDaoImpl extends GenericDaoBase sc = TemplateSearch.create(); + sc.setParameters("template_id", templateId); + Transaction txn = Transaction.currentTxn(); + txn.start(); + remove(sc); + txn.commit(); + + } + } 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 index c76e67b8c81..d2895fdf377 100644 --- 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 @@ -142,7 +142,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { s_logger.debug("there is already one in the cache store"); return objectInStoreMgr.get(data, cacheStore); } - + //TODO: consider multiple thread to create DataObject objOnCacheStore = cacheStore.create(data); @@ -155,7 +155,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { result = future.get(); if (result.isFailed()) { - cacheStore.delete(data); + objOnCacheStore.processEvent(Event.OperationFailed); } else { objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); return objOnCacheStore; @@ -168,7 +168,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { s_logger.debug("create cache storage failed: " + e.toString()); } finally { if (result == null) { - cacheStore.delete(data); + objOnCacheStore.processEvent(Event.OperationFailed); } } @@ -191,8 +191,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { } @Override - public DataObject deleteCacheObject(DataObject data) { - // TODO Auto-generated method stub - return null; + public boolean deleteCacheObject(DataObject data) { + return objectInStoreMgr.delete(data); } } \ No newline at end of file diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index dca892f0037..21615c9ee8d 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1456,8 +1456,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (privateTemplate == null) { Transaction txn = Transaction.currentTxn(); txn.start(); - // Remove the template_store_ref record first, otherwise, we cannot remove the template record due to FK constraints - this._tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); + // template_store_ref entries should have been removed using our DataObject.processEvent command in case of failure. + // Remove the template_zone_ref record + this._tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); // Remove the template record this._tmpltDao.expunge(templateId); From cb0659ab33fcb0b0b0b8daeadd0fd41576d11db4 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 12:01:53 -0700 Subject: [PATCH 226/303] CLOUDSTACK-2590: we should only search for active user templates when deleting an image store. --- .../cloud/api/query/dao/TemplateJoinDao.java | 2 + .../api/query/dao/TemplateJoinDaoImpl.java | 18 + .../cloud/api/query/vo/TemplateJoinVO.java | 15 + .../com/cloud/storage/StorageManagerImpl.java | 712 +++++++----------- setup/db/db/schema-410to420.sql | 3 +- 5 files changed, 315 insertions(+), 435 deletions(-) diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDao.java b/server/src/com/cloud/api/query/dao/TemplateJoinDao.java index 3897db54746..4d1de902daa 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDao.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDao.java @@ -39,4 +39,6 @@ public interface TemplateJoinDao extends GenericDao { List searchByIds(Long... ids); + List listActiveTemplates(long storeId); + } diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 0e5001be098..5a5ac785a1b 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -75,6 +75,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im private final SearchBuilder tmpltZoneSearch; + private final SearchBuilder activeTmpltSearch; + protected TemplateJoinDaoImpl() { @@ -92,6 +94,11 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im tmpltZoneSearch.and("downloadState", tmpltZoneSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); tmpltZoneSearch.done(); + activeTmpltSearch = createSearchBuilder(); + activeTmpltSearch.and("store_id", activeTmpltSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); + activeTmpltSearch.and("type", activeTmpltSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + activeTmpltSearch.done(); + // select distinct pair (template_id, zone_id) this._count = "select count(distinct id) from template_view WHERE "; } @@ -438,4 +445,15 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im + + @Override + public List listActiveTemplates(long storeId) { + SearchCriteria sc = activeTmpltSearch.create(); + sc.setParameters("store_id", storeId); + sc.setParameters("type", TemplateType.USER); + return searchIncludingRemoved(sc, null, null, false); + } + + + } diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index 77ce14afc1a..d47141d9b84 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -179,6 +179,9 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="data_center_name") private String dataCenterName; + @Column(name="store_id") + private Long dataStoreId; // this can be null for baremetal templates + @Column (name="download_state") @Enumerated(EnumType.STRING) private Status downloadState; @@ -1003,4 +1006,16 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { + public Long getDataStoreId() { + return dataStoreId; + } + + + + public void setDataStoreId(Long dataStoreId) { + this.dataStoreId = dataStoreId; + } + + + } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index ba6b3434ad6..3d92052c1e4 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -94,6 +94,8 @@ import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; +import com.cloud.api.query.dao.TemplateJoinDao; +import com.cloud.api.query.vo.TemplateJoinVO; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityManager; import com.cloud.capacity.CapacityState; @@ -251,6 +253,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected TemplateDataStoreDao _templateStoreDao = null; @Inject + protected TemplateJoinDao _templateViewDao = null; + @Inject protected VolumeDataStoreDao _volumeStoreDao = null; @Inject protected CapacityDao _capacityDao; @@ -305,7 +309,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject ConfigurationServer _configServer; - @Inject protected ResourceTagDao _resourceTagDao; + @Inject + protected ResourceTagDao _resourceTagDao; @Inject DataStoreManager _dataStoreMgr; @@ -313,26 +318,30 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C DataStoreProviderManager _dataStoreProviderMgr; @Inject private TemplateService _imageSrv; - @Inject EndPointSelector _epSelector; + @Inject + EndPointSelector _epSelector; protected List _storagePoolAllocators; + public List getStoragePoolAllocators() { - return _storagePoolAllocators; - } - public void setStoragePoolAllocators( - List _storagePoolAllocators) { - this._storagePoolAllocators = _storagePoolAllocators; - } + return _storagePoolAllocators; + } + + public void setStoragePoolAllocators(List _storagePoolAllocators) { + this._storagePoolAllocators = _storagePoolAllocators; + } protected List _discoverers; - public List getDiscoverers() { - return _discoverers; - } - public void setDiscoverers(List _discoverers) { - this._discoverers = _discoverers; - } - protected SearchBuilder HostTemplateStatesSearch; + public List getDiscoverers() { + return _discoverers; + } + + public void setDiscoverers(List _discoverers) { + this._discoverers = _discoverers; + } + + protected SearchBuilder HostTemplateStatesSearch; protected GenericSearchBuilder UpHostsInPoolSearch; protected SearchBuilder StoragePoolSearch; protected SearchBuilder LocalStorageSearch; @@ -347,7 +356,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C protected int _retry = 2; protected int _pingInterval = 60; // seconds protected int _hostRetry; - //protected BigDecimal _overProvisioningFactor = new BigDecimal(1); + // protected BigDecimal _overProvisioningFactor = new BigDecimal(1); private long _maxVolumeSizeInGb; private long _serverId; @@ -357,18 +366,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C private boolean _recreateSystemVmEnabled; - public boolean share(VMInstanceVO vm, List vols, HostVO host, - boolean cancelPreviousShare) throws StorageUnavailableException { + public boolean share(VMInstanceVO vm, List vols, HostVO host, boolean cancelPreviousShare) throws StorageUnavailableException { // if pool is in maintenance and it is the ONLY pool available; reject - List rootVolForGivenVm = _volsDao.findByInstanceAndType( - vm.getId(), Type.ROOT); + List rootVolForGivenVm = _volsDao.findByInstanceAndType(vm.getId(), Type.ROOT); if (rootVolForGivenVm != null && rootVolForGivenVm.size() > 0) { - boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0) - .getPoolId()); + boolean isPoolAvailable = isPoolAvailable(rootVolForGivenVm.get(0).getPoolId()); if (!isPoolAvailable) { - throw new StorageUnavailableException("Can not share " + vm, - rootVolForGivenVm.get(0).getPoolId()); + throw new StorageUnavailableException("Can not share " + vm, rootVolForGivenVm.get(0).getPoolId()); } } @@ -378,8 +383,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // available for (VolumeVO vol : vols) { if (vol.getRemoved() != null) { - s_logger.warn("Volume id:" + vol.getId() - + " is removed, cannot share on this instance"); + s_logger.warn("Volume id:" + vol.getId() + " is removed, cannot share on this instance"); // not ok to share return false; } @@ -394,10 +398,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C List pools = _storagePoolDao.listAll(); // if no pools or 1 pool which is in maintenance - if (pools == null - || pools.size() == 0 - || (pools.size() == 1 && pools.get(0).getStatus() - .equals(StoragePoolStatus.Maintenance))) { + if (pools == null || pools.size() == 0 || (pools.size() == 1 && pools.get(0).getStatus().equals(StoragePoolStatus.Maintenance))) { return false; } else { return true; @@ -405,10 +406,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public List ListByDataCenterHypervisor( - long datacenterId, HypervisorType type) { - List pools = _storagePoolDao - .listByDataCenterId(datacenterId); + public List ListByDataCenterHypervisor(long datacenterId, HypervisorType type) { + List pools = _storagePoolDao.listByDataCenterId(datacenterId); List retPools = new ArrayList(); for (StoragePoolVO pool : pools) { if (pool.getStatus() != StoragePoolStatus.Up) { @@ -425,35 +424,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override public boolean isLocalStorageActiveOnHost(Long hostId) { - List storagePoolHostRefs = _storagePoolHostDao - .listByHostId(hostId); + List storagePoolHostRefs = _storagePoolHostDao.listByHostId(hostId); for (StoragePoolHostVO storagePoolHostRef : storagePoolHostRefs) { - StoragePoolVO PrimaryDataStoreVO = _storagePoolDao - .findById(storagePoolHostRef.getPoolId()); - if (PrimaryDataStoreVO.getPoolType() == StoragePoolType.LVM - || PrimaryDataStoreVO.getPoolType() == StoragePoolType.EXT) { - SearchBuilder volumeSB = _volsDao - .createSearchBuilder(); - volumeSB.and("poolId", volumeSB.entity().getPoolId(), - SearchCriteria.Op.EQ); - volumeSB.and("removed", volumeSB.entity().getRemoved(), - SearchCriteria.Op.NULL); + StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(storagePoolHostRef.getPoolId()); + if (PrimaryDataStoreVO.getPoolType() == StoragePoolType.LVM || PrimaryDataStoreVO.getPoolType() == StoragePoolType.EXT) { + SearchBuilder volumeSB = _volsDao.createSearchBuilder(); + volumeSB.and("poolId", volumeSB.entity().getPoolId(), SearchCriteria.Op.EQ); + volumeSB.and("removed", volumeSB.entity().getRemoved(), SearchCriteria.Op.NULL); volumeSB.and("state", volumeSB.entity().getState(), SearchCriteria.Op.NIN); - SearchBuilder activeVmSB = _vmInstanceDao - .createSearchBuilder(); - activeVmSB.and("state", activeVmSB.entity().getState(), - SearchCriteria.Op.IN); - volumeSB.join("activeVmSB", activeVmSB, volumeSB.entity() - .getInstanceId(), activeVmSB.entity().getId(), - JoinBuilder.JoinType.INNER); + SearchBuilder activeVmSB = _vmInstanceDao.createSearchBuilder(); + activeVmSB.and("state", activeVmSB.entity().getState(), SearchCriteria.Op.IN); + volumeSB.join("activeVmSB", activeVmSB, volumeSB.entity().getInstanceId(), activeVmSB.entity().getId(), JoinBuilder.JoinType.INNER); SearchCriteria volumeSC = volumeSB.create(); volumeSC.setParameters("poolId", PrimaryDataStoreVO.getId()); volumeSC.setParameters("state", Volume.State.Expunging, Volume.State.Destroy); - volumeSC.setJoinParameters("activeVmSB", "state", - State.Starting, State.Running, State.Stopping, - State.Migrating); + volumeSC.setJoinParameters("activeVmSB", "state", State.Starting, State.Running, State.Stopping, State.Migrating); List volumes = _volsDao.search(volumeSC, null); if (volumes.size() > 0) { @@ -466,39 +453,34 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public StoragePool findStoragePool(DiskProfile dskCh, - final DataCenterVO dc, HostPodVO pod, Long clusterId, Long hostId, - VMInstanceVO vm, final Set avoid) { + public StoragePool findStoragePool(DiskProfile dskCh, final DataCenterVO dc, HostPodVO pod, Long clusterId, Long hostId, VMInstanceVO vm, + final Set avoid) { - VirtualMachineProfile profile = new VirtualMachineProfileImpl( - vm); + VirtualMachineProfile profile = new VirtualMachineProfileImpl(vm); for (StoragePoolAllocator allocator : _storagePoolAllocators) { - ExcludeList avoidList = new ExcludeList(); - for(StoragePool pool : avoid){ - avoidList.addPool(pool.getId()); - } - DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), clusterId, hostId, null, null); + ExcludeList avoidList = new ExcludeList(); + for (StoragePool pool : avoid) { + avoidList.addPool(pool.getId()); + } + DataCenterDeployment plan = new DataCenterDeployment(dc.getId(), pod.getId(), clusterId, hostId, null, null); - final List poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1); - if (poolList != null && !poolList.isEmpty()) { - return (StoragePool)this.dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary); - } + final List poolList = allocator.allocateToPool(dskCh, profile, plan, avoidList, 1); + if (poolList != null && !poolList.isEmpty()) { + return (StoragePool) this.dataStoreMgr.getDataStore(poolList.get(0).getId(), DataStoreRole.Primary); + } } return null; } @Override - public Answer[] sendToPool(StoragePool pool, Commands cmds) - throws StorageUnavailableException { + public Answer[] sendToPool(StoragePool pool, Commands cmds) throws StorageUnavailableException { return sendToPool(pool, null, null, cmds).second(); } @Override - public Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, - Command cmd) throws StorageUnavailableException { - Answer[] answers = sendToPool(pool, hostIdsToTryFirst, null, - new Commands(cmd)).second(); + public Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) throws StorageUnavailableException { + Answer[] answers = sendToPool(pool, hostIdsToTryFirst, null, new Commands(cmd)).second(); if (answers == null) { return null; } @@ -506,8 +488,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public Answer sendToPool(StoragePool pool, Command cmd) - throws StorageUnavailableException { + public Answer sendToPool(StoragePool pool, Command cmd) throws StorageUnavailableException { Answer[] answers = sendToPool(pool, new Commands(cmd)); if (answers == null) { return null; @@ -515,15 +496,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return answers[0]; } - public Long chooseHostForStoragePool(StoragePoolVO poolVO, - List avoidHosts, boolean sendToVmResidesOn, Long vmId) { + public Long chooseHostForStoragePool(StoragePoolVO poolVO, List avoidHosts, boolean sendToVmResidesOn, Long vmId) { if (sendToVmResidesOn) { if (vmId != null) { VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId); if (vmInstance != null) { Long hostId = vmInstance.getHostId(); - if (hostId != null - && !avoidHosts.contains(vmInstance.getHostId())) { + if (hostId != null && !avoidHosts.contains(vmInstance.getHostId())) { return hostId; } } @@ -534,8 +513,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C * cmd */ } - List poolHosts = _poolHostDao.listByHostStatus( - poolVO.getId(), Status.Up); + List poolHosts = _poolHostDao.listByHostStatus(poolVO.getId(), Status.Up); Collections.shuffle(poolHosts); if (poolHosts != null && poolHosts.size() > 0) { for (StoragePoolHostVO sphvo : poolHosts) { @@ -550,130 +528,91 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Override public boolean configure(String name, Map params) throws ConfigurationException { - - Map configs = _configDao.getConfiguration( - "management-server", params); + Map configs = _configDao.getConfiguration("management-server", params); _retry = NumbersUtil.parseInt(configs.get(Config.StartRetry.key()), 10); _pingInterval = NumbersUtil.parseInt(configs.get("ping.interval"), 60); _hostRetry = NumbersUtil.parseInt(configs.get("host.retry"), 2); - _storagePoolAcquisitionWaitSeconds = NumbersUtil.parseInt( - configs.get("pool.acquisition.wait.seconds"), 1800); - s_logger.info("pool.acquisition.wait.seconds is configured as " - + _storagePoolAcquisitionWaitSeconds + " seconds"); + _storagePoolAcquisitionWaitSeconds = NumbersUtil.parseInt(configs.get("pool.acquisition.wait.seconds"), 1800); + s_logger.info("pool.acquisition.wait.seconds is configured as " + _storagePoolAcquisitionWaitSeconds + " seconds"); - _agentMgr.registerForHostEvents(new StoragePoolMonitor(this, - _storagePoolDao), true, false, true); + _agentMgr.registerForHostEvents(new StoragePoolMonitor(this, _storagePoolDao), true, false, true); String storageCleanupEnabled = configs.get("storage.cleanup.enabled"); - _storageCleanupEnabled = (storageCleanupEnabled == null) ? true - : Boolean.parseBoolean(storageCleanupEnabled); + _storageCleanupEnabled = (storageCleanupEnabled == null) ? true : Boolean.parseBoolean(storageCleanupEnabled); - String value = _configDao.getValue(Config.CreateVolumeFromSnapshotWait - .toString()); - _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CreateVolumeFromSnapshotWait - .getDefaultValue())); + String value = _configDao.getValue(Config.CreateVolumeFromSnapshotWait.toString()); + _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CreateVolumeFromSnapshotWait.getDefaultValue())); value = _configDao.getValue(Config.CopyVolumeWait.toString()); - _copyvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); + _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); value = _configDao.getValue(Config.RecreateSystemVmEnabled.key()); _recreateSystemVmEnabled = Boolean.parseBoolean(value); value = _configDao.getValue(Config.StorageTemplateCleanupEnabled.key()); - _templateCleanupEnabled = (value == null ? true : Boolean - .parseBoolean(value)); + _templateCleanupEnabled = (value == null ? true : Boolean.parseBoolean(value)); String time = configs.get("storage.cleanup.interval"); _storageCleanupInterval = NumbersUtil.parseInt(time, 86400); - s_logger.info("Storage cleanup enabled: " + _storageCleanupEnabled - + ", interval: " + _storageCleanupInterval + s_logger.info("Storage cleanup enabled: " + _storageCleanupEnabled + ", interval: " + _storageCleanupInterval + ", template cleanup enabled: " + _templateCleanupEnabled); String workers = configs.get("expunge.workers"); int wrks = NumbersUtil.parseInt(workers, 10); - _executor = Executors.newScheduledThreadPool(wrks, - new NamedThreadFactory("StorageManager-Scavenger")); + _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("StorageManager-Scavenger")); - _agentMgr.registerForHostEvents( - ComponentContext.inject(LocalStoragePoolListener.class), true, - false, false); + _agentMgr.registerForHostEvents(ComponentContext.inject(LocalStoragePoolListener.class), true, false, false); - String maxVolumeSizeInGbString = _configDao - .getValue("storage.max.volume.size"); - _maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, - 2000); + String maxVolumeSizeInGbString = _configDao.getValue("storage.max.volume.size"); + _maxVolumeSizeInGb = NumbersUtil.parseLong(maxVolumeSizeInGbString, 2000); - String _customDiskOfferingMinSizeStr = _configDao - .getValue(Config.CustomDiskOfferingMinSize.toString()); - _customDiskOfferingMinSize = NumbersUtil.parseInt( - _customDiskOfferingMinSizeStr, Integer - .parseInt(Config.CustomDiskOfferingMinSize - .getDefaultValue())); - - String _customDiskOfferingMaxSizeStr = _configDao - .getValue(Config.CustomDiskOfferingMaxSize.toString()); - _customDiskOfferingMaxSize = NumbersUtil.parseInt( - _customDiskOfferingMaxSizeStr, Integer - .parseInt(Config.CustomDiskOfferingMaxSize - .getDefaultValue())); + String _customDiskOfferingMinSizeStr = _configDao.getValue(Config.CustomDiskOfferingMinSize.toString()); + _customDiskOfferingMinSize = NumbersUtil.parseInt(_customDiskOfferingMinSizeStr, + Integer.parseInt(Config.CustomDiskOfferingMinSize.getDefaultValue())); + String _customDiskOfferingMaxSizeStr = _configDao.getValue(Config.CustomDiskOfferingMaxSize.toString()); + _customDiskOfferingMaxSize = NumbersUtil.parseInt(_customDiskOfferingMaxSizeStr, + Integer.parseInt(Config.CustomDiskOfferingMaxSize.getDefaultValue())); _serverId = _msServer.getId(); - UpHostsInPoolSearch = _storagePoolHostDao - .createSearchBuilder(Long.class); - UpHostsInPoolSearch.selectField(UpHostsInPoolSearch.entity() - .getHostId()); + UpHostsInPoolSearch = _storagePoolHostDao.createSearchBuilder(Long.class); + UpHostsInPoolSearch.selectField(UpHostsInPoolSearch.entity().getHostId()); SearchBuilder hostSearch = _hostDao.createSearchBuilder(); hostSearch.and("status", hostSearch.entity().getStatus(), Op.EQ); - hostSearch.and("resourceState", hostSearch.entity().getResourceState(), - Op.EQ); - UpHostsInPoolSearch.join("hosts", hostSearch, hostSearch.entity() - .getId(), UpHostsInPoolSearch.entity().getHostId(), - JoinType.INNER); - UpHostsInPoolSearch.and("pool", UpHostsInPoolSearch.entity() - .getPoolId(), Op.EQ); + hostSearch.and("resourceState", hostSearch.entity().getResourceState(), Op.EQ); + UpHostsInPoolSearch.join("hosts", hostSearch, hostSearch.entity().getId(), UpHostsInPoolSearch.entity().getHostId(), JoinType.INNER); + UpHostsInPoolSearch.and("pool", UpHostsInPoolSearch.entity().getPoolId(), Op.EQ); UpHostsInPoolSearch.done(); StoragePoolSearch = _vmInstanceDao.createSearchBuilder(); SearchBuilder volumeSearch = _volumeDao.createSearchBuilder(); - volumeSearch.and("volumeType", volumeSearch.entity().getVolumeType(), - SearchCriteria.Op.EQ); - volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), - SearchCriteria.Op.EQ); + volumeSearch.and("volumeType", volumeSearch.entity().getVolumeType(), SearchCriteria.Op.EQ); + volumeSearch.and("poolId", volumeSearch.entity().getPoolId(), SearchCriteria.Op.EQ); volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ); - StoragePoolSearch.join("vmVolume", volumeSearch, volumeSearch.entity() - .getInstanceId(), StoragePoolSearch.entity().getId(), + StoragePoolSearch.join("vmVolume", volumeSearch, volumeSearch.entity().getInstanceId(), StoragePoolSearch.entity().getId(), JoinBuilder.JoinType.INNER); StoragePoolSearch.done(); LocalStorageSearch = _storagePoolDao.createSearchBuilder(); - SearchBuilder storageHostSearch = _storagePoolHostDao - .createSearchBuilder(); - storageHostSearch.and("hostId", storageHostSearch.entity().getHostId(), - SearchCriteria.Op.EQ); - LocalStorageSearch.join("poolHost", storageHostSearch, - storageHostSearch.entity().getPoolId(), LocalStorageSearch - .entity().getId(), JoinBuilder.JoinType.INNER); - LocalStorageSearch.and("type", LocalStorageSearch.entity() - .getPoolType(), SearchCriteria.Op.IN); + SearchBuilder storageHostSearch = _storagePoolHostDao.createSearchBuilder(); + storageHostSearch.and("hostId", storageHostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + LocalStorageSearch.join("poolHost", storageHostSearch, storageHostSearch.entity().getPoolId(), LocalStorageSearch.entity().getId(), + JoinBuilder.JoinType.INNER); + LocalStorageSearch.and("type", LocalStorageSearch.entity().getPoolType(), SearchCriteria.Op.IN); LocalStorageSearch.done(); - Volume.State.getStateMachine().registerListener( new VolumeStateListener()); + Volume.State.getStateMachine().registerListener(new VolumeStateListener()); return true; } - @Override public String getStoragePoolTags(long poolId) { - return _configMgr.listToCsvTags(_storagePoolDao - .searchForStoragePoolDetails(poolId, "true")); + return _configMgr.listToCsvTags(_storagePoolDao.searchForStoragePoolDetails(poolId, "true")); } @Override @@ -681,8 +620,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (_storageCleanupEnabled) { Random generator = new Random(); int initialDelay = generator.nextInt(_storageCleanupInterval); - _executor.scheduleWithFixedDelay(new StorageGarbageCollector(), - initialDelay, _storageCleanupInterval, TimeUnit.SECONDS); + _executor.scheduleWithFixedDelay(new StorageGarbageCollector(), initialDelay, _storageCleanupInterval, TimeUnit.SECONDS); } else { s_logger.debug("Storage cleanup is not enabled, so the storage cleanup thread is not being scheduled."); } @@ -709,12 +647,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } DataStore store = null; try { - StoragePoolVO pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), pInfo.getHostPath(), pInfo.getUuid()); - if(pool == null && host.getHypervisorType() == HypervisorType.VMware) { - // perform run-time upgrade. In versions prior to 2.2.12, there is a bug that we don't save local datastore info (host path is empty), this will cause us - // not able to distinguish multiple local datastores that may be available on the host, to support smooth migration, we + StoragePoolVO pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), pInfo.getHostPath(), + pInfo.getUuid()); + if (pool == null && host.getHypervisorType() == HypervisorType.VMware) { + // perform run-time upgrade. In versions prior to 2.2.12, there + // is a bug that we don't save local datastore info (host path + // is empty), this will cause us + // not able to distinguish multiple local datastores that may be + // available on the host, to support smooth migration, we // need to perform runtime upgrade here - if(pInfo.getHostPath().length() > 0) { + if (pInfo.getHostPath().length() > 0) { pool = _storagePoolDao.findPoolByHostPath(host.getDataCenterId(), host.getPodId(), pInfo.getHost(), "", pInfo.getUuid()); } } @@ -735,8 +677,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C store = lifeCycle.initialize(params); } else { - store = (DataStore) dataStoreMgr.getDataStore(pool.getId(), - DataStoreRole.Primary); + store = (DataStore) dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); } HostScope scope = new HostScope(host.getId(), host.getDataCenterId()); @@ -746,24 +687,20 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new ConnectionException(true, "Unable to setup the local storage pool for " + host, e); } - return (DataStore) dataStoreMgr.getDataStore(store.getId(), - DataStoreRole.Primary); + return (DataStore) dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); } @Override @SuppressWarnings("rawtypes") - public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) - throws ResourceInUseException, IllegalArgumentException, - UnknownHostException, ResourceUnavailableException { + public PrimaryDataStoreInfo createPool(CreateStoragePoolCmd cmd) throws ResourceInUseException, IllegalArgumentException, UnknownHostException, + ResourceUnavailableException { String providerName = cmd.getStorageProviderName(); - DataStoreProvider storeProvider = dataStoreProviderMgr - .getDataStoreProvider(providerName); + DataStoreProvider storeProvider = dataStoreProviderMgr.getDataStoreProvider(providerName); if (storeProvider == null) { storeProvider = dataStoreProviderMgr.getDefaultPrimaryDataStoreProvider(); if (storeProvider == null) { - throw new InvalidParameterValueException( - "can't find storage provider: " + providerName); + throw new InvalidParameterValueException("can't find storage provider: " + providerName); } } @@ -777,17 +714,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C try { scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase()); } catch (Exception e) { - throw new InvalidParameterValueException("invalid scope" - + scope); + throw new InvalidParameterValueException("invalid scope" + scope); } } if (scopeType == ScopeType.CLUSTER && clusterId == null) { - throw new InvalidParameterValueException( - "cluster id can't be null, if scope is cluster"); + throw new InvalidParameterValueException("cluster id can't be null, if scope is cluster"); } else if (scopeType == ScopeType.ZONE && zoneId == null) { - throw new InvalidParameterValueException( - "zone id can't be null, if scope is zone"); + throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); } Map ds = cmd.getDetails(); @@ -800,24 +734,19 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C Iterator it2 = d.entrySet().iterator(); while (it2.hasNext()) { Map.Entry entry = (Map.Entry) it2.next(); - details.put((String) entry.getKey(), - (String) entry.getValue()); + details.put((String) entry.getKey(), (String) entry.getValue()); } } } DataCenterVO zone = _dcDao.findById(cmd.getZoneId()); if (zone == null) { - throw new InvalidParameterValueException( - "unable to find zone by id " + zoneId); + throw new InvalidParameterValueException("unable to find zone by id " + zoneId); } // Check if zone is disabled Account account = UserContext.current().getCaller(); - if (Grouping.AllocationState.Disabled == zone.getAllocationState() - && !_accountMgr.isRootAdmin(account.getType())) { - throw new PermissionDeniedException( - "Cannot perform this operation, Zone is currently disabled: " - + zoneId); + if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(account.getType())) { + throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zoneId); } Map params = new HashMap(); @@ -836,8 +765,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C store = lifeCycle.initialize(params); if (scopeType == ScopeType.CLUSTER) { - ClusterScope clusterScope = new ClusterScope(clusterId, podId, - zoneId); + ClusterScope clusterScope = new ClusterScope(clusterId, podId, zoneId); lifeCycle.attachCluster(store, clusterScope); } else if (scopeType == ScopeType.ZONE) { ZoneScope zoneScope = new ZoneScope(zoneId); @@ -848,21 +776,18 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new CloudRuntimeException("Failed to add data store", e); } - return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(store.getId(), - DataStoreRole.Primary); + return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); } @Override - public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) - throws IllegalArgumentException { + public PrimaryDataStoreInfo updateStoragePool(UpdateStoragePoolCmd cmd) throws IllegalArgumentException { // Input validation Long id = cmd.getId(); List tags = cmd.getTags(); StoragePoolVO pool = _storagePoolDao.findById(id); if (pool == null) { - throw new IllegalArgumentException( - "Unable to find storage pool with ID: " + id); + throw new IllegalArgumentException("Unable to find storage pool with ID: " + id); } if (tags != null) { @@ -877,8 +802,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C _storagePoolDao.updateDetails(id, details); } - return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(pool.getId(), - DataStoreRole.Primary); + return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); } @Override @@ -890,30 +814,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C StoragePoolVO sPool = _storagePoolDao.findById(id); if (sPool == null) { s_logger.warn("Unable to find pool:" + id); - throw new InvalidParameterValueException( - "Unable to find pool by id " + id); + throw new InvalidParameterValueException("Unable to find pool by id " + id); } if (sPool.getStatus() != StoragePoolStatus.Maintenance) { - s_logger.warn("Unable to delete storage id: " + id - + " due to it is not in Maintenance state"); - throw new InvalidParameterValueException( - "Unable to delete storage due to it is not in Maintenance state, id: " - + id); + s_logger.warn("Unable to delete storage id: " + id + " due to it is not in Maintenance state"); + throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id); } if (sPool.isLocal()) { s_logger.warn("Unable to delete local storage id:" + id); - throw new InvalidParameterValueException( - "Unable to delete local storage id: " + id); + throw new InvalidParameterValueException("Unable to delete local storage id: " + id); } Pair vlms = _volsDao.getCountAndTotalByPool(id); if (forced) { if (vlms.first() > 0) { - Pair nonDstrdVlms = _volsDao - .getNonDestroyedCountAndTotalByPool(id); + Pair nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(id); if (nonDstrdVlms.first() > 0) { - throw new CloudRuntimeException("Cannot delete pool " - + sPool.getName() + " as there are associated " + throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool"); } // force expunge non-destroyed volumes @@ -933,20 +850,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // Check if the pool has associated volumes in the volumes table // If it does , then you cannot delete the pool if (vlms.first() > 0) { - throw new CloudRuntimeException("Cannot delete pool " - + sPool.getName() + " as there are associated vols" - + " for this pool"); + throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated vols" + " for this pool"); } } // First get the host_id from storage_pool_host_ref for given pool id - StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool - .getId()); + StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId()); if (lock == null) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Failed to acquire lock when deleting PrimaryDataStoreVO with ID: " - + sPool.getId()); + s_logger.debug("Failed to acquire lock when deleting PrimaryDataStoreVO with ID: " + sPool.getId()); } return false; } @@ -954,30 +867,27 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C _storagePoolDao.releaseFromLockTable(lock.getId()); s_logger.trace("Released lock for storage pool " + id); - DataStoreProvider storeProvider = dataStoreProviderMgr - .getDataStoreProvider(sPool.getStorageProviderName()); + DataStoreProvider storeProvider = dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName()); DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle(); - DataStore store = dataStoreMgr.getDataStore( - sPool.getId(), DataStoreRole.Primary); + DataStore store = dataStoreMgr.getDataStore(sPool.getId(), DataStoreRole.Primary); return lifeCycle.deleteDataStore(store); } @Override - public void connectHostToSharedPool(long hostId, long poolId) - throws StorageUnavailableException { - StoragePool pool = (StoragePool)this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); + public void connectHostToSharedPool(long hostId, long poolId) throws StorageUnavailableException { + StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); assert (pool.isShared()) : "Now, did you actually read the name of this method?"; s_logger.debug("Adding pool " + pool.getName() + " to host " + hostId); - DataStoreProvider provider = dataStoreProviderMgr - .getDataStoreProvider(pool.getStorageProviderName()); + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(pool.getStorageProviderName()); HypervisorHostListener listener = hostListeners.get(provider.getName()); listener.hostConnect(hostId, pool.getId()); } @Override - public BigDecimal getStorageOverProvisioningFactor(Long dcId){ - return new BigDecimal(_configServer.getConfigValue(Config.StorageOverprovisioningFactor.key(), Config.ConfigurationParameterScope.zone.toString(), dcId)); + public BigDecimal getStorageOverProvisioningFactor(Long dcId) { + return new BigDecimal(_configServer.getConfigValue(Config.StorageOverprovisioningFactor.key(), + Config.ConfigurationParameterScope.zone.toString(), dcId)); } @Override @@ -992,13 +902,24 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C long totalOverProvCapacity; if (storagePool.getPoolType() == StoragePoolType.NetworkFilesystem) { BigDecimal overProvFactor = getStorageOverProvisioningFactor(storagePool.getDataCenterId()); - totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(storagePool.getCapacityBytes())).longValue();// All this for the inaccuracy of floats for big number multiplication. + totalOverProvCapacity = overProvFactor.multiply(new BigDecimal(storagePool.getCapacityBytes())).longValue();// All + // this + // for + // the + // inaccuracy + // of + // floats + // for + // big + // number + // multiplication. } else { totalOverProvCapacity = storagePool.getCapacityBytes(); } if (capacities.size() == 0) { - CapacityVO capacity = new CapacityVO(storagePool.getId(), storagePool.getDataCenterId(), storagePool.getPodId(), storagePool.getClusterId(), allocated, totalOverProvCapacity, capacityType); + CapacityVO capacity = new CapacityVO(storagePool.getId(), storagePool.getDataCenterId(), storagePool.getPodId(), + storagePool.getClusterId(), allocated, totalOverProvCapacity, capacityType); AllocationState allocationState = null; if (storagePool.getScope() == ScopeType.ZONE) { DataCenterVO dc = ApiDBUtils.findZoneById(storagePool.getDataCenterId()); @@ -1006,8 +927,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } else { allocationState = _configMgr.findClusterAllocationState(ApiDBUtils.findClusterById(storagePool.getClusterId())); } - CapacityState capacityState = (allocationState == AllocationState.Disabled) ? - CapacityState.Disabled : CapacityState.Enabled; + CapacityState capacityState = (allocationState == AllocationState.Disabled) ? CapacityState.Disabled : CapacityState.Enabled; capacity.setCapacityState(capacityState); _capacityDao.persist(capacity); @@ -1040,7 +960,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public Pair sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List hostIdsToAvoid, Commands cmds) throws StorageUnavailableException { + public Pair sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List hostIdsToAvoid, Commands cmds) + throws StorageUnavailableException { List hostIds = getUpHostsInPool(pool.getId()); Collections.shuffle(hostIds); if (hostIdsToTryFirst != null) { @@ -1055,7 +976,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C hostIds.removeAll(hostIdsToAvoid); } if (hostIds == null || hostIds.isEmpty()) { - throw new StorageUnavailableException("Unable to send command to the pool " + pool.getId() + " due to there is no enabled hosts up in this cluster", pool.getId()); + throw new StorageUnavailableException("Unable to send command to the pool " + pool.getId() + + " due to there is no enabled hosts up in this cluster", pool.getId()); } for (Long hostId : hostIds) { try { @@ -1078,7 +1000,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public Pair sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List hostIdsToAvoid, Command cmd) throws StorageUnavailableException { + public Pair sendToPool(StoragePool pool, long[] hostIdsToTryFirst, List hostIdsToAvoid, Command cmd) + throws StorageUnavailableException { Commands cmds = new Commands(cmd); Pair result = sendToPool(pool, hostIdsToTryFirst, hostIdsToAvoid, cmds); return new Pair(result.first(), result.second()[0]); @@ -1098,17 +1021,20 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C try { List unusedTemplatesInPool = _tmpltMgr.getUnusedTemplatesInPool(pool); - s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + " templates to clean up in storage pool: " + pool.getName()); + s_logger.debug("Storage pool garbage collector found " + unusedTemplatesInPool.size() + + " templates to clean up in storage pool: " + pool.getName()); for (VMTemplateStoragePoolVO templatePoolVO : unusedTemplatesInPool) { if (templatePoolVO.getDownloadState() != VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - s_logger.debug("Storage pool garbage collector is skipping templatePoolVO with ID: " + templatePoolVO.getId() + " because it is not completely downloaded."); + s_logger.debug("Storage pool garbage collector is skipping templatePoolVO with ID: " + templatePoolVO.getId() + + " because it is not completely downloaded."); continue; } if (!templatePoolVO.getMarkedForGC()) { templatePoolVO.setMarkedForGC(true); _vmTemplatePoolDao.update(templatePoolVO.getId(), templatePoolVO); - s_logger.debug("Storage pool garbage collector has marked templatePoolVO with ID: " + templatePoolVO.getId() + " for garbage collection."); + s_logger.debug("Storage pool garbage collector has marked templatePoolVO with ID: " + templatePoolVO.getId() + + " for garbage collection."); continue; } @@ -1120,7 +1046,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } - cleanupSecondaryStorage(recurring); List vols = _volsDao.listVolumesToBeDestroyed(); @@ -1134,22 +1059,21 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } - // remove snapshots in Error state List snapshots = _snapshotDao.listAllByStatus(Snapshot.State.Error); for (SnapshotVO snapshotVO : snapshots) { - try{ + try { _snapshotDao.expunge(snapshotVO.getId()); - }catch (Exception e) { + } catch (Exception e) { s_logger.warn("Unable to destroy " + snapshotVO.getId(), e); } } - }finally { + } finally { scanLock.unlock(); } } - }finally { + } finally { scanLock.releaseRef(); } } @@ -1170,8 +1094,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } return list; } catch (Exception e) { - s_logger.debug("failed to get all volumes who has snapshots in secondary storage " - + storeId + " due to " + e.getMessage()); + s_logger.debug("failed to get all volumes who has snapshots in secondary storage " + storeId + " due to " + e.getMessage()); return null; } @@ -1192,8 +1115,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } return list; } catch (Exception e) { - s_logger.debug("failed to get all snapshots for a volume " - + volumeId + " due to " + e.getMessage()); + s_logger.debug("failed to get all snapshots for a volume " + volumeId + " due to " + e.getMessage()); return null; } } @@ -1312,7 +1234,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (installPath != null) { EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getTO(), destroyedStoreVO.getVolumeId(), destroyedStoreVO.getInstallPath()); + DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getTO(), destroyedStoreVO.getVolumeId(), + destroyedStoreVO.getInstallPath()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + destroyedStoreVO + " due to " @@ -1342,16 +1265,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // poolId is null only if volume is destroyed, which has been checked // before. assert poolId != null; - StoragePoolVO PrimaryDataStoreVO = _storagePoolDao - .findById(poolId); + StoragePoolVO PrimaryDataStoreVO = _storagePoolDao.findById(poolId); assert PrimaryDataStoreVO != null; return PrimaryDataStoreVO.getUuid(); } @Override @DB - public PrimaryDataStoreInfo preparePrimaryStorageForMaintenance( - Long primaryStorageId) throws ResourceUnavailableException, + public PrimaryDataStoreInfo preparePrimaryStorageForMaintenance(Long primaryStorageId) throws ResourceUnavailableException, InsufficientCapacityException { Long userId = UserContext.current().getCallerUserId(); User user = _userDao.findById(userId); @@ -1368,43 +1289,31 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new InvalidParameterValueException(msg); } - List spes = _storagePoolDao.listBy( - primaryStorage.getDataCenterId(), primaryStorage.getPodId(), - primaryStorage.getClusterId(), ScopeType.CLUSTER); + List spes = _storagePoolDao.listBy(primaryStorage.getDataCenterId(), primaryStorage.getPodId(), primaryStorage.getClusterId(), + ScopeType.CLUSTER); for (StoragePoolVO sp : spes) { if (sp.getStatus() == StoragePoolStatus.PrepareForMaintenance) { - throw new CloudRuntimeException( - "Only one storage pool in a cluster can be in PrepareForMaintenance mode, " - + sp.getId() - + " is already in PrepareForMaintenance mode "); + throw new CloudRuntimeException("Only one storage pool in a cluster can be in PrepareForMaintenance mode, " + sp.getId() + + " is already in PrepareForMaintenance mode "); } } - if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) - && !primaryStorage.getStatus().equals( - StoragePoolStatus.ErrorInMaintenance)) { - throw new InvalidParameterValueException("Primary storage with id " - + primaryStorageId - + " is not ready for migration, as the status is:" + if (!primaryStorage.getStatus().equals(StoragePoolStatus.Up) && !primaryStorage.getStatus().equals(StoragePoolStatus.ErrorInMaintenance)) { + throw new InvalidParameterValueException("Primary storage with id " + primaryStorageId + " is not ready for migration, as the status is:" + primaryStorage.getStatus().toString()); } - DataStoreProvider provider = dataStoreProviderMgr - .getDataStoreProvider(primaryStorage.getStorageProviderName()); + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName()); DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - DataStore store = dataStoreMgr.getDataStore( - primaryStorage.getId(), DataStoreRole.Primary); + DataStore store = dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary); lifeCycle.maintain(store); - return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore( - primaryStorage.getId(), DataStoreRole.Primary); + return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary); } @Override @DB - public PrimaryDataStoreInfo cancelPrimaryStorageForMaintenance( - CancelPrimaryStorageMaintenanceCmd cmd) - throws ResourceUnavailableException { + public PrimaryDataStoreInfo cancelPrimaryStorageForMaintenance(CancelPrimaryStorageMaintenanceCmd cmd) throws ResourceUnavailableException { Long primaryStorageId = cmd.getId(); Long userId = UserContext.current().getCallerUserId(); User user = _userDao.findById(userId); @@ -1419,24 +1328,17 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new InvalidParameterValueException(msg); } - if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) - || primaryStorage.getStatus().equals( - StoragePoolStatus.PrepareForMaintenance)) { - throw new StorageUnavailableException("Primary storage with id " - + primaryStorageId - + " is not ready to complete migration, as the status is:" - + primaryStorage.getStatus().toString(), primaryStorageId); + if (primaryStorage.getStatus().equals(StoragePoolStatus.Up) || primaryStorage.getStatus().equals(StoragePoolStatus.PrepareForMaintenance)) { + throw new StorageUnavailableException("Primary storage with id " + primaryStorageId + + " is not ready to complete migration, as the status is:" + primaryStorage.getStatus().toString(), primaryStorageId); } - DataStoreProvider provider = dataStoreProviderMgr - .getDataStoreProvider(primaryStorage.getStorageProviderName()); + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider(primaryStorage.getStorageProviderName()); DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - DataStore store = dataStoreMgr.getDataStore( - primaryStorage.getId(), DataStoreRole.Primary); + DataStore store = dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary); lifeCycle.cancelMaintain(store); - return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore( - primaryStorage.getId(), DataStoreRole.Primary); + return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(primaryStorage.getId(), DataStoreRole.Primary); } protected class StorageGarbageCollector implements Runnable { @@ -1458,35 +1360,26 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public void onManagementNodeJoined(List nodeList, - long selfNodeId) { + public void onManagementNodeJoined(List nodeList, long selfNodeId) { // TODO Auto-generated method stub } @Override - public void onManagementNodeLeft(List nodeList, - long selfNodeId) { + public void onManagementNodeLeft(List nodeList, long selfNodeId) { for (ManagementServerHostVO vo : nodeList) { if (vo.getMsid() == _serverId) { - s_logger.info("Cleaning up storage maintenance jobs associated with Management server" - + vo.getMsid()); - List poolIds = _storagePoolWorkDao - .searchForPoolIdsForPendingWorkJobs(vo.getMsid()); + s_logger.info("Cleaning up storage maintenance jobs associated with Management server" + vo.getMsid()); + List poolIds = _storagePoolWorkDao.searchForPoolIdsForPendingWorkJobs(vo.getMsid()); if (poolIds.size() > 0) { for (Long poolId : poolIds) { - StoragePoolVO pool = _storagePoolDao - .findById(poolId); + StoragePoolVO pool = _storagePoolDao.findById(poolId); // check if pool is in an inconsistent state if (pool != null - && (pool.getStatus().equals( - StoragePoolStatus.ErrorInMaintenance) - || pool.getStatus() - .equals(StoragePoolStatus.PrepareForMaintenance) || pool - .getStatus() - .equals(StoragePoolStatus.CancelMaintenance))) { - _storagePoolWorkDao.removePendingJobsOnMsRestart( - vo.getMsid(), poolId); + && (pool.getStatus().equals(StoragePoolStatus.ErrorInMaintenance) + || pool.getStatus().equals(StoragePoolStatus.PrepareForMaintenance) || pool.getStatus().equals( + StoragePoolStatus.CancelMaintenance))) { + _storagePoolWorkDao.removePendingJobsOnMsRestart(vo.getMsid(), poolId); pool.setStatus(StoragePoolStatus.ErrorInMaintenance); _storagePoolDao.update(poolId, pool); } @@ -1513,34 +1406,29 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C hosts.add(hostId); } else { List stores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); - if (stores != null){ - for (DataStore store : stores){ + if (stores != null) { + for (DataStore store : stores) { hosts.add(store.getId()); } } - } + } - CapacityVO capacity = new CapacityVO(hostId, zoneId, null, null, 0, 0, - CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE); + CapacityVO capacity = new CapacityVO(hostId, zoneId, null, null, 0, 0, CapacityVO.CAPACITY_TYPE_SECONDARY_STORAGE); for (Long id : hosts) { StorageStats stats = ApiDBUtils.getSecondaryStorageStatistics(id); if (stats == null) { continue; } - capacity.setUsedCapacity(stats.getByteUsed() - + capacity.getUsedCapacity()); - capacity.setTotalCapacity(stats.getCapacityBytes() - + capacity.getTotalCapacity()); + capacity.setUsedCapacity(stats.getByteUsed() + capacity.getUsedCapacity()); + capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity()); } return capacity; } @Override - public CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, - Long podId, Long zoneId) { - SearchCriteria sc = _storagePoolDao - .createSearchCriteria(); + public CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long podId, Long zoneId) { + SearchCriteria sc = _storagePoolDao.createSearchCriteria(); List pools = new ArrayList(); if (zoneId != null) { @@ -1564,30 +1452,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C pools = _storagePoolDao.search(sc, null); } - CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, - 0, 0, CapacityVO.CAPACITY_TYPE_STORAGE); + CapacityVO capacity = new CapacityVO(poolId, zoneId, podId, clusterId, 0, 0, CapacityVO.CAPACITY_TYPE_STORAGE); for (StoragePoolVO PrimaryDataStoreVO : pools) { - StorageStats stats = ApiDBUtils - .getStoragePoolStatistics(PrimaryDataStoreVO.getId()); + StorageStats stats = ApiDBUtils.getStoragePoolStatistics(PrimaryDataStoreVO.getId()); if (stats == null) { continue; } - capacity.setUsedCapacity(stats.getByteUsed() - + capacity.getUsedCapacity()); - capacity.setTotalCapacity(stats.getCapacityBytes() - + capacity.getTotalCapacity()); + capacity.setUsedCapacity(stats.getByteUsed() + capacity.getUsedCapacity()); + capacity.setTotalCapacity(stats.getCapacityBytes() + capacity.getTotalCapacity()); } return capacity; } @Override public PrimaryDataStoreInfo getStoragePool(long id) { - return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(id, - DataStoreRole.Primary); + return (PrimaryDataStoreInfo) dataStoreMgr.getDataStore(id, DataStoreRole.Primary); } - - @Override @DB public List listByStoragePool(long storagePoolId) { @@ -1602,11 +1483,9 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @DB public StoragePoolVO findLocalStorageOnHost(long hostId) { SearchCriteria sc = LocalStorageSearch.create(); - sc.setParameters("type", new Object[] { StoragePoolType.Filesystem, - StoragePoolType.LVM }); + sc.setParameters("type", new Object[] { StoragePoolType.Filesystem, StoragePoolType.LVM }); sc.setJoinParameters("poolHost", "hostId", hostId); - List storagePools = _storagePoolDao - .search(sc, null); + List storagePools = _storagePoolDao.search(sc, null); if (!storagePools.isEmpty()) { return storagePools.get(0); } else { @@ -1618,33 +1497,25 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C public Host updateSecondaryStorage(long secStorageId, String newUrl) { HostVO secHost = _hostDao.findById(secStorageId); if (secHost == null) { - throw new InvalidParameterValueException( - "Can not find out the secondary storage id: " - + secStorageId); + throw new InvalidParameterValueException("Can not find out the secondary storage id: " + secStorageId); } if (secHost.getType() != Host.Type.SecondaryStorage) { - throw new InvalidParameterValueException("host: " + secStorageId - + " is not a secondary storage"); + throw new InvalidParameterValueException("host: " + secStorageId + " is not a secondary storage"); } URI uri = null; try { uri = new URI(UriUtils.encodeURIComponent(newUrl)); if (uri.getScheme() == null) { - throw new InvalidParameterValueException("uri.scheme is null " - + newUrl + ", add nfs:// as a prefix"); + throw new InvalidParameterValueException("uri.scheme is null " + newUrl + ", add nfs:// as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("nfs")) { - if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") - || uri.getPath() == null - || uri.getPath().equalsIgnoreCase("")) { - throw new InvalidParameterValueException( - "Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { + throw new InvalidParameterValueException("Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); } } } catch (URISyntaxException e) { - throw new InvalidParameterValueException(newUrl - + " is not a valid uri"); + throw new InvalidParameterValueException(newUrl + " is not a valid uri"); } String oldUrl = secHost.getStorageUrl(); @@ -1653,9 +1524,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C try { oldUri = new URI(UriUtils.encodeURIComponent(oldUrl)); if (!oldUri.getScheme().equalsIgnoreCase(uri.getScheme())) { - throw new InvalidParameterValueException( - "can not change old scheme:" + oldUri.getScheme() - + " to " + uri.getScheme()); + throw new InvalidParameterValueException("can not change old scheme:" + oldUri.getScheme() + " to " + uri.getScheme()); } } catch (URISyntaxException e) { s_logger.debug("Failed to get uri from " + oldUrl); @@ -1668,8 +1537,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return secHost; } - - @Override public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) { @@ -1692,7 +1559,8 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C private boolean checkUsagedSpace(StoragePool pool) { StatsCollector sc = StatsCollector.getInstance(); - double storageUsedThreshold = Double.parseDouble(_configServer.getConfigValue(Config.StorageCapacityDisableThreshold.key(), Config.ConfigurationParameterScope.zone.toString(), pool.getDataCenterId())); + double storageUsedThreshold = Double.parseDouble(_configServer.getConfigValue(Config.StorageCapacityDisableThreshold.key(), + Config.ConfigurationParameterScope.zone.toString(), pool.getDataCenterId())); if (sc != null) { long totalSize = pool.getCapacityBytes(); StorageStats stats = sc.getStoragePoolStats(pool.getId()); @@ -1702,21 +1570,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (stats != null) { double usedPercentage = ((double) stats.getByteUsed() / (double) totalSize); if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking pool " + pool.getId() - + " for storage, totalSize: " - + pool.getCapacityBytes() + ", usedBytes: " - + stats.getByteUsed() + ", usedPct: " - + usedPercentage + ", disable threshold: " - + storageUsedThreshold); + s_logger.debug("Checking pool " + pool.getId() + " for storage, totalSize: " + pool.getCapacityBytes() + ", usedBytes: " + + stats.getByteUsed() + ", usedPct: " + usedPercentage + ", disable threshold: " + storageUsedThreshold); } if (usedPercentage >= storageUsedThreshold) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Insufficient space on pool: " - + pool.getId() - + " since its usage percentage: " - + usedPercentage - + " has crossed the pool.storage.capacity.disablethreshold: " - + storageUsedThreshold); + s_logger.debug("Insufficient space on pool: " + pool.getId() + " since its usage percentage: " + usedPercentage + + " has crossed the pool.storage.capacity.disablethreshold: " + storageUsedThreshold); } return false; } @@ -1727,8 +1587,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public boolean storagePoolHasEnoughSpace(List volumes, - StoragePool pool) { + public boolean storagePoolHasEnoughSpace(List volumes, StoragePool pool) { if (volumes == null || volumes.isEmpty()) return false; @@ -1737,16 +1596,13 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // allocated space includes template of specified volume StoragePoolVO poolVO = _storagePoolDao.findById(pool.getId()); - long allocatedSizeWithtemplate = _capacityMgr.getAllocatedPoolCapacity( - poolVO, null); + long allocatedSizeWithtemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, null); long totalAskingSize = 0; for (Volume volume : volumes) { if (volume.getTemplateId() != null) { - VMTemplateVO tmpl = _templateDao.findById(volume - .getTemplateId()); + VMTemplateVO tmpl = _templateDao.findById(volume.getTemplateId()); if (tmpl.getFormat() != ImageFormat.ISO) { - allocatedSizeWithtemplate = _capacityMgr - .getAllocatedPoolCapacity(poolVO, tmpl); + allocatedSizeWithtemplate = _capacityMgr.getAllocatedPoolCapacity(poolVO, tmpl); } } if (volume.getState() != Volume.State.Ready) @@ -1755,48 +1611,36 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C long totalOverProvCapacity; if (pool.getPoolType() == StoragePoolType.NetworkFilesystem) { - totalOverProvCapacity = getStorageOverProvisioningFactor(pool.getDataCenterId()).multiply( - new BigDecimal(pool.getCapacityBytes())).longValue(); + totalOverProvCapacity = getStorageOverProvisioningFactor(pool.getDataCenterId()).multiply(new BigDecimal(pool.getCapacityBytes())) + .longValue(); } else { totalOverProvCapacity = pool.getCapacityBytes(); } - double storageAllocatedThreshold = Double.parseDouble(_configServer.getConfigValue(Config.StorageAllocatedCapacityDisableThreshold.key(), Config.ConfigurationParameterScope.zone.toString(), pool.getDataCenterId())); + double storageAllocatedThreshold = Double.parseDouble(_configServer.getConfigValue(Config.StorageAllocatedCapacityDisableThreshold.key(), + Config.ConfigurationParameterScope.zone.toString(), pool.getDataCenterId())); if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking pool: " + pool.getId() - + " for volume allocation " + volumes.toString() - + ", maxSize : " + totalOverProvCapacity - + ", totalAllocatedSize : " + allocatedSizeWithtemplate - + ", askingSize : " + totalAskingSize - + ", allocated disable threshold: " + s_logger.debug("Checking pool: " + pool.getId() + " for volume allocation " + volumes.toString() + ", maxSize : " + totalOverProvCapacity + + ", totalAllocatedSize : " + allocatedSizeWithtemplate + ", askingSize : " + totalAskingSize + ", allocated disable threshold: " + storageAllocatedThreshold); } - double usedPercentage = (allocatedSizeWithtemplate + totalAskingSize) - / (double) (totalOverProvCapacity); + double usedPercentage = (allocatedSizeWithtemplate + totalAskingSize) / (double) (totalOverProvCapacity); if (usedPercentage > storageAllocatedThreshold) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Insufficient un-allocated capacity on: " - + pool.getId() - + " for volume allocation: " - + volumes.toString() - + " since its allocated percentage: " - + usedPercentage - + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold: " - + storageAllocatedThreshold + ", skipping this pool"); + s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for volume allocation: " + volumes.toString() + + " since its allocated percentage: " + usedPercentage + + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold: " + storageAllocatedThreshold + + ", skipping this pool"); } return false; } if (totalOverProvCapacity < (allocatedSizeWithtemplate + totalAskingSize)) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Insufficient un-allocated capacity on: " - + pool.getId() + " for volume allocation: " - + volumes.toString() - + ", not enough storage, maxSize : " - + totalOverProvCapacity + ", totalAllocatedSize : " - + allocatedSizeWithtemplate + ", askingSize : " - + totalAskingSize); + s_logger.debug("Insufficient un-allocated capacity on: " + pool.getId() + " for volume allocation: " + volumes.toString() + + ", not enough storage, maxSize : " + totalOverProvCapacity + ", totalAllocatedSize : " + allocatedSizeWithtemplate + + ", askingSize : " + totalAskingSize); } return false; } @@ -1809,24 +1653,20 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C createCapacityEntry(storage, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, 0); } - @Override - public synchronized boolean registerHostListener(String providerName, - HypervisorHostListener listener) { + public synchronized boolean registerHostListener(String providerName, HypervisorHostListener listener) { hostListeners.put(providerName, listener); return true; } @Override - public Answer sendToPool(long poolId, Command cmd) - throws StorageUnavailableException { + public Answer sendToPool(long poolId, Command cmd) throws StorageUnavailableException { // TODO Auto-generated method stub return null; } @Override - public Answer[] sendToPool(long poolId, Commands cmd) - throws StorageUnavailableException { + public Answer[] sendToPool(long poolId, Commands cmd) throws StorageUnavailableException { // TODO Auto-generated method stub return null; } @@ -1838,8 +1678,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } @Override - public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, - InvalidParameterValueException { + public ImageStore discoverImageStore(AddImageStoreCmd cmd) throws IllegalArgumentException, DiscoveryException, InvalidParameterValueException { String providerName = cmd.getProviderName(); DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(providerName); @@ -1854,21 +1693,23 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C String url = cmd.getUrl(); Map details = cmd.getDetails(); ScopeType scopeType = ScopeType.ZONE; - if ( dcId == null ){ + if (dcId == null) { scopeType = ScopeType.REGION; } // check if scope is supported by store provider - if ( !((ImageStoreProvider)storeProvider).isScopeSupported(scopeType)){ + if (!((ImageStoreProvider) storeProvider).isScopeSupported(scopeType)) { throw new InvalidParameterValueException("Image store provider " + providerName + " does not support scope " + scopeType); } - // check if we have already image stores from other different providers, we currently are not supporting image stores from different + // check if we have already image stores from other different providers, + // we currently are not supporting image stores from different // providers co-existing List imageStores = _imageStoreDao.listImageStores(); - for ( ImageStoreVO store : imageStores){ - if (!store.getProviderName().equalsIgnoreCase(providerName)){ - throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + " already added"); + for (ImageStoreVO store : imageStores) { + if (!store.getProviderName().equalsIgnoreCase(providerName)) { + throw new InvalidParameterValueException("You can only add new image stores from the same provider " + store.getProviderName() + + " already added"); } } @@ -1888,7 +1729,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } - Map params = new HashMap(); params.put("zoneId", dcId); params.put("url", cmd.getUrl()); @@ -1915,13 +1755,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C this._imageSrv.addSystemVMTemplatesToSecondary(store); } - // associate builtin template with zones associated with this image store + // associate builtin template with zones associated with this image + // store this.associateCrosszoneTemplatesToZone(dcId); return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Image); } - private void associateCrosszoneTemplatesToZone(Long zoneId){ + private void associateCrosszoneTemplatesToZone(Long zoneId) { VMTemplateZoneVO tmpltZone; List allTemplates = _vmTemplateDao.listAll(); @@ -1961,24 +1802,28 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } _accountMgr.checkAccessAndSpecifyAuthority(UserContext.current().getCaller(), store.getDataCenterId()); - // Verify that there are no live snapshot, template, volume on the image store to be deleted + // Verify that there are no live snapshot, template, volume on the image + // store to be deleted List snapshots = _snapshotStoreDao.listByStoreId(storeId, DataStoreRole.Image); - if ( snapshots != null && snapshots.size() > 0 ){ - throw new CloudRuntimeException("Cannot delete image store with active snapshots backup!"); + if (snapshots != null && snapshots.size() > 0) { + throw new InvalidParameterValueException("Cannot delete image store with active snapshots backup!"); } List volumes = _volumeStoreDao.listByStoreId(storeId); - if ( volumes != null && volumes.size() > 0 ){ - throw new CloudRuntimeException("Cannot delete image store with active volumes backup!"); + if (volumes != null && volumes.size() > 0) { + throw new InvalidParameterValueException("Cannot delete image store with active volumes backup!"); } - List templates = _templateStoreDao.listByStoreId(storeId); - if ( templates != null && templates.size() > 0 ){ - throw new CloudRuntimeException("Cannot delete image store with active templates backup!"); + + // search if there are user templates stored on this image store, excluding system, builtin templates + List templates = this._templateViewDao.listActiveTemplates(storeId); + if (templates != null && templates.size() > 0) { + throw new InvalidParameterValueException("Cannot delete image store with active templates backup!"); } // ready to delete Transaction txn = Transaction.currentTxn(); txn.start(); - // first delete from image_store_details table, we need to do that since we are not actually deleting record from main + // first delete from image_store_details table, we need to do that since + // we are not actually deleting record from main // image_data_store table, so delete cascade will not work _imageStoreDetailsDao.deleteDetails(storeId); _snapshotStoreDao.deletePrimaryRecordsForStore(storeId); @@ -1988,6 +1833,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C txn.commit(); return true; } + @Override public ImageStore createCacheStore(CreateCacheStoreCmd cmd) { String providerName = cmd.getProviderName(); @@ -2021,7 +1867,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C throw new InvalidParameterValueException("zone id can't be null, if scope is zone"); } - // Check if the zone exists in the system DataCenterVO zone = _dcDao.findById(dcId); if (zone == null) { @@ -2057,5 +1902,4 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C return (ImageStore) _dataStoreMgr.getDataStore(store.getId(), DataStoreRole.ImageCache); } - } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 556b7f319dc..134e44db532 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -177,7 +177,7 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `parent_snapshot_id` bigint unsigned DEFAULT 0, `install_path` varchar(255), `state` varchar(255) NOT NULL, - `removed` datetime COMMENT 'date removed if not null', + -- `removed` datetime COMMENT 'date removed if not null', `update_count` bigint unsigned, `updated` datetime, PRIMARY KEY (`id`), @@ -1752,6 +1752,7 @@ CREATE VIEW `cloud`.`template_view` AS data_center.uuid data_center_uuid, data_center.name data_center_name, launch_permission.account_id lp_account_id, + template_store_ref.store_id, template_store_ref.download_state, template_store_ref.download_pct, template_store_ref.error_str, From a4e6784e0b5bbef8135271a0c1c5f990ed2115b3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 14:43:32 -0700 Subject: [PATCH 227/303] CLOUDSTACK-2578: NPE in deleting template from S3. --- .../datastore/driver/CloudStackImageStoreDriverImpl.java | 5 +++-- .../storage/datastore/driver/S3ImageStoreDriverImpl.java | 9 ++++----- .../datastore/driver/SwiftImageStoreDriverImpl.java | 5 +++-- .../storage/resource/NfsSecondaryStorageResource.java | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 0c46d5e2ea7..71afc13e13c 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -276,8 +276,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { // TODO: need to understand why we need to mark destroyed in // template_store_ref table here instead of in callback. // Currently I did that in callback, so I removed previous code to mark template_host_ref - - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + if ( sZoneId != null ){ + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + } // get installpath of this template on image store TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 9487bbe2832..1c6e17e8e1b 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -286,11 +286,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { eventType = EventTypes.EVENT_TEMPLATE_DELETE; } - // TODO: need to understand why we need to mark destroyed in - // template_store_ref table here instead of in callback. - // Currently I did that in callback, so I removed previous code to mark template_host_ref - - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + if ( sZoneId != null ){ + //TODO: how to handle region wide usage data where sZoneId == null + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + } List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 69e03495b2b..590b653bdff 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -281,8 +281,9 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { // TODO: need to understand why we need to mark destroyed in // template_store_ref table here instead of in callback. // Currently I did that in callback, so I removed previous code to mark template_host_ref - - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + if (sZoneId != null){ + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + } List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 24b2e0b8c2d..6fbb06b3f2c 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1535,7 +1535,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S final String bucket = s3.getBucketName(); try { S3Utils.deleteDirectory(s3, bucket, path); - return new Answer(cmd, true, String.format("Deleted template %1%s from bucket %2$s.", path, bucket)); + return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket)); } catch (Exception e) { final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); From 2aab3c88491c286acf2eb61aa8298ad6c1ce4bb1 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 14:55:07 -0700 Subject: [PATCH 228/303] CLOUDSTACK-2594: Failed to add Secondary storage for second zone through old addSecondaryStorage api. --- server/src/com/cloud/storage/StorageManagerImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 3d92052c1e4..0313b491261 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1687,6 +1687,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (storeProvider == null) { throw new InvalidParameterValueException("can't find image store provider: " + providerName); } + providerName = storeProvider.getName(); // ignored passed provider name and use default image store provider name } Long dcId = cmd.getZoneId(); From f5732fe3bff9970eb913bfbd9a8912dbb8d8592a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 16:50:02 -0700 Subject: [PATCH 229/303] Consolidate code to use UriUtils.validateUrl instead of repeating code several places. --- .../template/HttpTemplateDownloader.java | 42 +---------------- .../template/S3TemplateDownloader.java | 46 ++----------------- .../com/cloud/storage/VolumeManagerImpl.java | 42 +---------------- .../template/HypervisorTemplateAdapter.java | 36 ++------------- utils/src/com/cloud/utils/UriUtils.java | 5 +- 5 files changed, 13 insertions(+), 158 deletions(-) diff --git a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java index e832c0291e5..4c0e14530bd 100644 --- a/core/src/com/cloud/storage/template/HttpTemplateDownloader.java +++ b/core/src/com/cloud/storage/template/HttpTemplateDownloader.java @@ -50,6 +50,7 @@ import com.cloud.agent.api.storage.Proxy; import com.cloud.storage.StorageLayer; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.Pair; +import com.cloud.utils.UriUtils; /** * Download a template file using HTTP @@ -128,7 +129,7 @@ public class HttpTemplateDownloader implements TemplateDownloader { } toFile = f.getAbsolutePath(); - Pair hostAndPort = validateUrl(downloadUrl); + Pair hostAndPort = UriUtils.validateUrl(downloadUrl); if (proxy != null) { client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); @@ -159,45 +160,6 @@ public class HttpTemplateDownloader implements TemplateDownloader { } - private Pair validateUrl(String url) throws IllegalArgumentException { - try { - URI uri = new URI(url); - if (!uri.getScheme().equalsIgnoreCase("http") && !uri.getScheme().equalsIgnoreCase("https") ) { - throw new IllegalArgumentException("Unsupported scheme for url"); - } - int port = uri.getPort(); - if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80, 8080 and 443 are allowed"); - } - - if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { - port = 443; - } else if (port == -1 && uri.getScheme().equalsIgnoreCase("http")) { - port = 80; - } - - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { - throw new IllegalArgumentException("Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); - } - return new Pair(host, port); - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException("Unable to resolve " + host); - } - } catch (IllegalArgumentException iae) { - s_logger.warn("Failed uri validation check: " + iae.getMessage()); - throw iae; - } catch (URISyntaxException use) { - s_logger.warn("Failed uri syntax check: " + use.getMessage()); - throw new IllegalArgumentException(use.getMessage()); - } - } - @Override public long download(boolean resume, DownloadCompleteCallback callback) { switch (status) { diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index 43b582ccecf..5ca6d338f5e 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -61,6 +61,7 @@ import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.S3TO; import com.cloud.utils.Pair; import com.cloud.utils.S3Utils; +import com.cloud.utils.UriUtils; /** * Download a template file using HTTP @@ -132,7 +133,8 @@ public class S3TemplateDownloader implements TemplateDownloader { this.request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler); this.completionCallback = callback; - Pair hostAndPort = validateUrl(downloadUrl); + Pair hostAndPort = UriUtils.validateUrl(downloadUrl); + this.fileName = StringUtils.substringAfterLast(downloadUrl, "/"); if (proxy != null) { client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); @@ -163,48 +165,6 @@ public class S3TemplateDownloader implements TemplateDownloader { } - private Pair validateUrl(String url) throws IllegalArgumentException { - try { - URI uri = new URI(url); - if (!uri.getScheme().equalsIgnoreCase("http") && !uri.getScheme().equalsIgnoreCase("https") ) { - throw new IllegalArgumentException("Unsupported scheme for url"); - } - int port = uri.getPort(); - if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80, 8080 and 443 are allowed"); - } - - if (port == -1 && uri.getScheme().equalsIgnoreCase("https")) { - port = 443; - } else if (port == -1 && uri.getScheme().equalsIgnoreCase("http")) { - port = 80; - } - - this.fileName = StringUtils.substringAfterLast(url, "/"); - - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { - throw new IllegalArgumentException("Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); - } - return new Pair(host, port); - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException("Unable to resolve " + host); - } - - } catch (IllegalArgumentException iae) { - s_logger.warn("Failed uri validation check: " + iae.getMessage()); - throw iae; - } catch (URISyntaxException use) { - s_logger.warn("Failed uri syntax check: " + use.getMessage()); - throw new IllegalArgumentException(use.getMessage()); - } - } - @Override public long download(boolean resume, DownloadCompleteCallback callback) { switch (status) { diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 2aa4192d5be..38f995930b2 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -481,7 +481,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { + " is an invalid for the format " + format.toLowerCase()); } - validateUrl(url); + UriUtils.validateUrl(url); // Check that the resource limit for secondary storage won't be exceeded _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage, @@ -2478,47 +2478,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } - private String validateUrl(String url) { - try { - URI uri = new URI(url); - if ((uri.getScheme() == null) - || (!uri.getScheme().equalsIgnoreCase("http") - && !uri.getScheme().equalsIgnoreCase("https") && !uri - .getScheme().equalsIgnoreCase("file"))) { - throw new IllegalArgumentException( - "Unsupported scheme for url: " + url); - } - int port = uri.getPort(); - if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { - throw new IllegalArgumentException( - "Only ports 80, 8080 and 443 are allowed"); - } - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() - || hostAddr.isLinkLocalAddress() - || hostAddr.isLoopbackAddress() - || hostAddr.isMulticastAddress()) { - throw new IllegalArgumentException( - "Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new IllegalArgumentException( - "IPV6 addresses not supported (" - + hostAddr.getHostAddress() + ")"); - } - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException("Unable to resolve " + host); - } - - return uri.toString(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid URL " + url); - } - - } @Override public boolean canVmRestartOnAnotherServer(long vmId) { diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index 74bae35ef75..e1d535b2a1a 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -87,36 +87,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { return TemplateAdapterType.Hypervisor.getName(); } - private String validateUrl(String url) { - try { - URI uri = new URI(url); - if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http") - && !uri.getScheme().equalsIgnoreCase("https") && !uri.getScheme().equalsIgnoreCase("file"))) { - throw new IllegalArgumentException("Unsupported scheme for url: " + url); - } - - int port = uri.getPort(); - if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { - throw new IllegalArgumentException("Only ports 80, 8080 and 443 are allowed"); - } - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { - throw new IllegalArgumentException("Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); - } - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException("Unable to resolve " + host); - } - - return uri.toString(); - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Invalid URL " + url); - } - } @Override public TemplateProfile prepare(RegisterIsoCmd cmd) throws ResourceAllocationException { @@ -128,7 +98,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { throw new InvalidParameterValueException("Please specify a valid iso"); } - profile.setUrl(validateUrl(url)); + UriUtils.validateUrl(url); + profile.setUrl(url); // Check that the resource limit for secondary storage won't be exceeded _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); @@ -160,7 +131,8 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { throw new InvalidParameterValueException("Please specify a valid URL. URL:" + url + " is an invalid for the format " + cmd.getFormat().toLowerCase()); } - profile.setUrl(validateUrl(url)); + UriUtils.validateUrl(url); + profile.setUrl(url); // Check that the resource limit for secondary storage won't be exceeded _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(cmd.getEntityOwnerId()), ResourceType.secondary_storage, UriUtils.getRemoteSize(url)); diff --git a/utils/src/com/cloud/utils/UriUtils.java b/utils/src/com/cloud/utils/UriUtils.java index 2673177ad96..b9d54d5cbc4 100644 --- a/utils/src/com/cloud/utils/UriUtils.java +++ b/utils/src/com/cloud/utils/UriUtils.java @@ -133,8 +133,9 @@ public class UriUtils { public static Pair validateUrl(String url) throws IllegalArgumentException { try { URI uri = new URI(url); - if (!uri.getScheme().equalsIgnoreCase("http") && !uri.getScheme().equalsIgnoreCase("https") ) { - throw new IllegalArgumentException("Unsupported scheme for url"); + if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("http") + && !uri.getScheme().equalsIgnoreCase("https") && !uri.getScheme().equalsIgnoreCase("file"))) { + throw new IllegalArgumentException("Unsupported scheme for url: " + url); } int port = uri.getPort(); if (!(port == 80 || port == 8080 || port == 443 || port == -1)) { From 235825dc337978cf97f59ea689feab44072adc32 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 16:51:12 -0700 Subject: [PATCH 230/303] Properly updated destroyed column in template_store_ref and volume_store_ref in deleting template or volume. --- .../cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java | 3 +++ .../cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index d41733d6d29..a90a2f620e0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -136,6 +136,9 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase Date: Tue, 21 May 2013 16:53:38 -0700 Subject: [PATCH 231/303] CLOUDSTACK-2584: fix create template from s3 --- .../cloudstack/storage/to/ImageStoreTO.java | 1 - .../motion/AncientDataMotionStrategy.java | 106 +++------------ .../resource/NfsSecondaryStorageResource.java | 124 +++++++----------- 3 files changed, 70 insertions(+), 161 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java index 28d5ef3d6aa..96e94794c57 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -74,5 +74,4 @@ public class ImageStoreTO implements DataStoreTO { public DataStoreRole getRole() { return this.role; } - } 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 index cea40691858..c0a3ec63448 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -137,37 +137,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return true; } - @DB - protected Answer copyVolumeFromImage(DataObject srcData, DataObject destData) { - String value = configDao.getValue(Config.CopyVolumeWait.key()); - int _copyvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - - if (needCacheStorage(srcData, destData)) { - //need to copy it to image cache store - Scope destScope = destData.getDataStore().getScope(); - if (destScope instanceof ClusterScope){ - ClusterScope clusterScope = (ClusterScope)destScope; - destScope = new ZoneScope(clusterScope.getZoneId()); - } else if (destScope instanceof HostScope){ - HostScope hostScope = (HostScope)destScope; - destScope = new ZoneScope(hostScope.getZoneId()); - } - DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); - CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); - EndPoint ep = selector.select(cacheData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; - } else { - //handle copy it to/from cache store - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _copyvolumewait); - EndPoint ep = selector.select(srcData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; - } - } - - private Answer copyTemplate(DataObject srcData, DataObject destData) { + protected Answer copyObject(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); if (needCacheStorage(srcData, destData)) { @@ -233,7 +203,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait); EndPoint ep = selector.select(snapObj, volObj); Answer answer = ep.sendMessage(cmd); - + return answer; } catch (Exception e) { s_logger.error(basicErrMsg, e); @@ -275,30 +245,24 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { 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 + + if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.VOLUME) { answer = copyVolumeFromSnapshot(srcData, destData); } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.TEMPLATE) { answer = createTemplateFromSnapshot(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) { + && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary && destData.getDataStore().getRole() == DataStoreRole.Primary) { answer = copyVolumeBetweenPools(srcData, destData); } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) { answer = copySnapshot(srcData, destData); + } else { + answer = copyObject(srcData, destData); } if (answer != null && !answer.getResult()) { @@ -337,58 +301,26 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return answer; } - - private Answer createTemplateFromVolume(DataObject srcData, - DataObject destData) { - - String value = configDao - .getValue(Config.CreatePrivateTemplateFromVolumeWait.toString()); - int _createprivatetemplatefromvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CreatePrivateTemplateFromVolumeWait - .getDefaultValue())); - - if (needCacheStorage(srcData, destData)) { - //need to copy it to image cache store - DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); - CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _createprivatetemplatefromvolumewait); - EndPoint ep = selector.select(cacheData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; - } else { - //handle copy it to/from cache store - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _createprivatetemplatefromvolumewait); - EndPoint ep = selector.select(srcData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; - } - } - protected Answer copySnapshot(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.BackupSnapshotWait.toString()); int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); DataObject cacheData = null; - Answer answer = null; try { - if (needCacheStorage(srcData, destData)) { - cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); + if (needCacheStorage(srcData, destData)) { + cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); - cmd.setCacheTO(cacheData.getTO()); - EndPoint ep = selector.select(srcData, destData); - answer = ep.sendMessage(cmd); - } else { - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); - EndPoint ep = selector.select(srcData, destData); - answer = ep.sendMessage(cmd); - } - // clean up cache entry in case of failure - if (answer == null || !answer.getResult()) { - if (cacheData != null) { - cacheMgr.deleteCacheObject(cacheData); - } - } + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); + cmd.setCacheTO(cacheData.getTO()); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); return answer; + } else { + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); + EndPoint ep = selector.select(srcData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } } catch (Exception e) { s_logger.debug("copy snasphot failed: " + e.toString()); if (cacheData != null) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 6fbb06b3f2c..8dca6f52206 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.storage.resource; import static com.cloud.utils.S3Utils.getDirectory; +import static com.cloud.utils.S3Utils.putFile; import static com.cloud.utils.StringUtils.join; import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; import static java.lang.String.format; @@ -27,6 +28,7 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; +import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; @@ -118,7 +120,9 @@ import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.VhdProcessor; import com.cloud.utils.NumbersUtil; import com.cloud.utils.S3Utils; +import com.cloud.utils.S3Utils.ClientOptions; import com.cloud.utils.S3Utils.FileNamingStrategy; +import com.cloud.utils.S3Utils.ObjectNamingStrategy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; @@ -214,8 +218,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((DownloadTemplateFromSwiftToSecondaryStorageCommand) cmd); } else if (cmd instanceof UploadTemplateToSwiftFromSecondaryStorageCommand) { return execute((UploadTemplateToSwiftFromSecondaryStorageCommand) cmd); - } else if (cmd instanceof UploadTemplateToS3FromSecondaryStorageCommand) { - return execute((UploadTemplateToS3FromSecondaryStorageCommand) cmd); } else if (cmd instanceof CleanupSnapshotBackupCommand) { return execute((CleanupSnapshotBackupCommand) cmd); } else if (cmd instanceof CopyCommand) { @@ -424,6 +426,17 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } return new CopyCmdAnswer(""); } + + protected Answer copyFromNfsToImage(CopyCommand cmd) { + DataTO destData = cmd.getDestTO(); + DataStoreTO destDataStore = destData.getDataStore(); + + if (destDataStore instanceof S3TO) { + return copyFromNfsToS3(cmd); + } else { + return new CopyCmdAnswer("unsupported "); + } + } protected Answer execute(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); @@ -440,6 +453,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S NfsTO destImageStore = (NfsTO)destDataStore; return this.copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore); } + + if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) { + return copyFromNfsToImage(cmd); + } return Answer.createUnsupportedCommandAnswer(cmd); @@ -608,86 +625,47 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private Answer execute(UploadTemplateToS3FromSecondaryStorageCommand cmd) { - /* - final S3TO s3 = cmd.getS3(); - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); - - try { - final S3TO s3 = cmd.getS3(); - final Long accountId = cmd.getAccountId(); - final Long templateId = cmd.getTemplateId(); - + protected Answer copyFromNfsToS3(CopyCommand cmd) { + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); + DataStoreTO srcDataStore = srcData.getDataStore(); + NfsTO srcStore = (NfsTO)srcDataStore; + DataStoreTO destDataStore = destData.getDataStore(); + + final S3TO s3 = (S3TO)destDataStore; + try { - final String templatePath = determineStorageTemplatePath( - cmd.getStoragePath(), accountId, templateId); + srcStore.getUrl(), srcData.getPath()); if (s_logger.isDebugEnabled()) { - s_logger.debug("Found template id " + templateId - + " account id " + accountId + " from directory " + s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3."); } - if (!_storage.isDirectory(templatePath)) { - final String errMsg = format("S3 Sync Failure: Directory %1$s" - + "for template id %2$s does not exist.", templatePath, - templateId); - s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); - } - - if (!_storage.isFile(templatePath + "/template.properties")) { - final String errMsg = format("S3 Sync Failure: Template id " - + "%1$s does not exist on the file system.", - templatePath); - s_logger.error(errMsg); - return new Answer(cmd, false, errMsg); - } - - if (s_logger.isDebugEnabled()) { - s_logger.debug(format( - "Pushing template id %1$s from %2$s to S3...", - templateId, templatePath)); - } - final String bucket = s3.getBucketName(); - putDirectory(s3, bucket, _storage.getFile(templatePath), - new FilenameFilter() { - @Override - public boolean accept(final File directory, - final String fileName) { - File fileToUpload = new File(directory.getAbsolutePath() + "/" + fileName); - return !fileName.startsWith(".") && !fileToUpload.isDirectory(); - } - }, new ObjectNamingStrategy() { - @Override - public String determineKey(final File file) { - s_logger.debug(String - .format("Determining key using account id %1$s and template id %2$s", - accountId, templateId)); - return join( - asList(determineS3TemplateDirectory( - accountId, templateId), file - .getName()), S3Utils.SEPARATOR); - } - }); - - return new Answer( - cmd, - true, - format("Uploaded the contents of directory %1$s for template id %2$s to S3 bucket %3$s", - templatePath, templateId, bucket)); - + final File srcFile = _storage.getFile(templatePath); + String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName(); + putFile(s3, srcFile, bucket, key); + + DataTO retObj = null; + if (destData.getObjectType() == DataObjectType.TEMPLATE) { + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(key); + newTemplate.setSize(srcFile.length()); + retObj = newTemplate; + } else if (destData.getObjectType() == DataObjectType.VOLUME) { + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(key); + newVol.setSize(srcFile.length()); + retObj = newVol; + } + + return new CopyCmdAnswer(retObj); } catch (Exception e) { - - final String errMsg = format("Failed to upload template id %1$s", - templateId); - s_logger.error(errMsg, e); - return new Answer(cmd, false, errMsg); - */ - return new Answer(cmd, false, "not supported "); + s_logger.error("failed to upload" + srcData.getPath(), e); + return new CopyCmdAnswer("failed to upload" + srcData.getPath() + e.toString()); + } } String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) { From efd249d61d953bb2c34943fb3d6f3bd9f2ce63aa Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 21 May 2013 17:34:39 -0700 Subject: [PATCH 232/303] fix build --- client/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/client/pom.xml b/client/pom.xml index 8ffba2be871..7fe9e96f672 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -199,11 +199,6 @@ cloud-engine-storage-cache ${project.version} - - org.apache.cloudstack - cloud-engine-storage-backup - ${project.version} - org.apache.cloudstack cloud-engine-storage-image From 536feab856379d89370a05453e065b143a3159a8 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 21 May 2013 17:47:38 -0700 Subject: [PATCH 233/303] when copy volume to secondary storage, need to add full volume path --- .../hypervisor/xen/resource/XenServerStorageProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index bdc3d30542f..b4bcf20d362 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -990,7 +990,7 @@ public class XenServerStorageProcessor implements StorageProcessor { String destVolumeUUID = destVdi.getUuid(conn); VolumeObjectTO newVol = new VolumeObjectTO(); - newVol.setPath(destVolumeUUID); + newVol.setPath(destVolume.getPath() + File.separator + destVolumeUUID + ".vhd"); newVol.setSize(srcVolume.getSize()); return new CopyCmdAnswer(newVol); } catch (Exception e) { From 383be568b3a6d9b3fb8d38e3f74e19c6c9e08eb2 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 21 May 2013 19:13:29 -0700 Subject: [PATCH 234/303] CLOUDSTACK-2527: enable attach/detach xs tool iso --- .../storage/to/TemplateObjectTO.java | 4 ++- .../src/com/cloud/storage/VMTemplateVO.java | 10 ++++++ .../storage/image/store/TemplateObject.java | 26 +++++++++------ engine/storage/pom.xml | 5 --- .../vmware/VmwareServerDiscoverer.java | 2 +- .../xen/discoverer/XcpServerDiscoverer.java | 2 +- .../resource/XenServerStorageProcessor.java | 32 +++++++++++++------ server/pom.xml | 5 --- .../com/cloud/api/query/QueryManagerImpl.java | 4 +-- .../cloud/api/query/vo/TemplateJoinVO.java | 17 +++++++++- setup/db/db/schema-410to420.sql | 1 + 11 files changed, 73 insertions(+), 35 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 9e7e9ef452f..3d7a901e352 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -68,7 +68,9 @@ public class TemplateObjectTO implements DataTO { this.accountId = template.getAccountId(); this.name = template.getUniqueName(); this.format = template.getFormat(); - this.imageDataStore = template.getDataStore().getTO(); + if (template.getDataStore() != null) { + this.imageDataStore = template.getDataStore().getTO(); + } } @Override diff --git a/engine/schema/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java index 06cb1b8f28b..e64c83a8b5b 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java @@ -175,6 +175,16 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObjectcloud-engine-api ${project.version} - - org.apache.cloudstack - cloud-secondary-storage - ${project.version} - mysql mysql-connector-java diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java index 00647d92b67..1d7300bd2e2 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java @@ -466,7 +466,7 @@ public class VmwareServerDiscoverer extends DiscovererBase implements Long id; if (tmplt == null) { id = _tmpltDao.getNextInSequence(Long.class, "id"); - VMTemplateVO template = new VMTemplateVO(id, isoName, isoName, + VMTemplateVO template = VMTemplateVO.createPreHostIso(id, isoName, isoName, ImageFormat.ISO, true, true, TemplateType.PERHOST, null, null, true, 64, Account.ACCOUNT_ID_SYSTEM, null, "VMware Tools Installer ISO", false, 1, false, diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java index 536a1f88432..5698218e4f8 100755 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/discoverer/XcpServerDiscoverer.java @@ -543,7 +543,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L Long id; if (tmplt == null) { id = _tmpltDao.getNextInSequence(Long.class, "id"); - VMTemplateVO template = new VMTemplateVO(id, isoName, isoName, ImageFormat.ISO, true, true, + VMTemplateVO template = VMTemplateVO.createPreHostIso(id, isoName, isoName, ImageFormat.ISO, true, true, TemplateType.PERHOST, null, null, true, 64, Account.ACCOUNT_ID_SYSTEM, null, "xen-pv-drv-iso", false, 1, false, HypervisorType.XenServer); _tmpltDao.persist(template); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index b4bcf20d362..4a623fc1271 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -103,12 +103,18 @@ public class XenServerStorageProcessor implements StorageProcessor { DataTO data = disk.getData(); DataStoreTO store = data.getDataStore(); - if (!(store instanceof NfsTO)) { - s_logger.debug("Can't attach a iso which is not created on nfs: "); - return new AttachAnswer("Can't attach a iso which is not created on nfs: "); + String isoURL = null; + if (store == null) { + TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); + isoURL = iso.getName(); + } else { + if (!(store instanceof NfsTO)) { + s_logger.debug("Can't attach a iso which is not created on nfs: "); + return new AttachAnswer("Can't attach a iso which is not created on nfs: "); + } + NfsTO nfsStore = (NfsTO)store; + isoURL = nfsStore.getUrl() + File.separator + data.getPath(); } - NfsTO nfsStore = (NfsTO)store; - String isoURL = nfsStore.getUrl() + File.separator + data.getPath(); String vmName = cmd.getVmName(); try { @@ -237,12 +243,18 @@ public class XenServerStorageProcessor implements StorageProcessor { DataTO data = disk.getData(); DataStoreTO store = data.getDataStore(); - if (!(store instanceof NfsTO)) { - s_logger.debug("Can't attach a iso which is not created on nfs: "); - return new DettachAnswer("Can't attach a iso which is not created on nfs: "); + String isoURL = null; + if (store == null) { + TemplateObjectTO iso = (TemplateObjectTO)disk.getData(); + isoURL = iso.getName(); + } else { + if (!(store instanceof NfsTO)) { + s_logger.debug("Can't attach a iso which is not created on nfs: "); + return new AttachAnswer("Can't attach a iso which is not created on nfs: "); + } + NfsTO nfsStore = (NfsTO)store; + isoURL = nfsStore.getUrl() + File.separator + data.getPath(); } - NfsTO nfsStore = (NfsTO)store; - String isoURL = nfsStore.getUrl() + File.separator + data.getPath(); try { Connection conn = this.hypervisorResource.getConnection(); diff --git a/server/pom.xml b/server/pom.xml index a29f9f1286a..6385bf2f233 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -100,11 +100,6 @@ cloud-framework-events ${project.version} - - org.apache.cloudstack - cloud-framework-ipc - ${project.version} - install diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java index df61391e639..adcce409ebb 100644 --- a/server/src/com/cloud/api/query/QueryManagerImpl.java +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java @@ -69,6 +69,7 @@ import org.apache.cloudstack.api.command.user.volume.ListResourceDetailsCmd; import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.api.response.*; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.query.QueryService; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -2712,8 +2713,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService { } if (onlyReady) { - sc.addAnd("downloadState", SearchCriteria.Op.EQ, Status.DOWNLOADED); - sc.addAnd("destroyed", SearchCriteria.Op.EQ, false); + sc.addAnd("state", SearchCriteria.Op.EQ, TemplateState.Ready); } if (zoneId != null) { diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index d47141d9b84..ef6d1ebce17 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -28,6 +28,7 @@ import javax.persistence.TemporalType; import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.server.ResourceTag.TaggedResourceType; @@ -239,7 +240,9 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="tag_customer") private String tagCustomer; - + @Column(name="state") + @Enumerated(value=EnumType.STRING) + private TemplateState state; public TemplateJoinVO() { } @@ -1018,4 +1021,16 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { + public TemplateState getState() { + return state; + } + + + + public void setState(TemplateState state) { + this.state = state; + } + + + } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 134e44db532..aecb93884ff 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1724,6 +1724,7 @@ CREATE VIEW `cloud`.`template_view` AS vm_template.display_text, vm_template.enable_password, vm_template.guest_os_id, + vm_template.state, guest_os.uuid guest_os_uuid, guest_os.display_name guest_os_name, vm_template.bootable, From f23f341922c951655a6dd0c3577f224456e70eb8 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 22:11:54 -0700 Subject: [PATCH 235/303] Handle CopyCmdAnswer in VolumeObject.processEvent for image and imageCache, and fix a bug in selecting endpoint. --- .../motion/AncientDataMotionStrategy.java | 88 ++++++++++++------- .../endpoint/DefaultEndPointSelector.java | 5 +- .../storage/volume/VolumeObject.java | 10 ++- 3 files changed, 67 insertions(+), 36 deletions(-) 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 index c0a3ec63448..1e99e9efbe2 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -140,28 +140,44 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected Answer copyObject(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); - if (needCacheStorage(srcData, destData)) { - //need to copy it to image cache store - Scope destScope = destData.getDataStore().getScope(); - if (destScope instanceof ClusterScope){ - ClusterScope clusterScope = (ClusterScope)destScope; - destScope = new ZoneScope(clusterScope.getZoneId()); - } else if (destScope instanceof HostScope){ - HostScope hostScope = (HostScope)destScope; - destScope = new ZoneScope(hostScope.getZoneId()); + Answer answer = null; + DataObject cacheData = null; + try { + if (needCacheStorage(srcData, destData)) { + // need to copy it to image cache store + Scope destScope = destData.getDataStore().getScope(); + if (destScope instanceof ClusterScope) { + ClusterScope clusterScope = (ClusterScope) destScope; + destScope = new ZoneScope(clusterScope.getZoneId()); + } else if (destScope instanceof HostScope) { + HostScope hostScope = (HostScope) destScope; + destScope = new ZoneScope(hostScope.getZoneId()); + } + cacheData = cacheMgr.createCacheObject(srcData, destScope); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); + EndPoint ep = selector.select(cacheData, destData); + answer = ep.sendMessage(cmd); + } else { + // handle copy it to/from cache store + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait); + EndPoint ep = selector.select(srcData, destData); + answer = ep.sendMessage(cmd); + } + // clean up cache entry in case of failure + if (answer == null || !answer.getResult()) { + if (cacheData != null) { + cacheMgr.deleteCacheObject(cacheData); + } } - DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); - CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); - EndPoint ep = selector.select(cacheData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; - } else { - //handle copy it to/from cache store - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _primaryStorageDownloadWait); - EndPoint ep = selector.select(srcData, destData); - Answer answer = ep.sendMessage(cmd); return answer; + } catch (Exception e) { + s_logger.debug("copy object failed: " + e.toString()); + if (cacheData != null) { + cacheMgr.deleteCacheObject(cacheData); + } + throw new CloudRuntimeException(e.toString()); } + } protected DataObject cacheSnapshotChain(SnapshotInfo snapshot) { @@ -203,7 +219,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait); EndPoint ep = selector.select(snapObj, volObj); Answer answer = ep.sendMessage(cmd); - + return answer; } catch (Exception e) { s_logger.error(basicErrMsg, e); @@ -245,7 +261,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { Answer answer = null; String errMsg = null; try { - + if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.VOLUME) { answer = copyVolumeFromSnapshot(srcData, destData); @@ -306,21 +322,27 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); DataObject cacheData = null; + Answer answer = null; try { - if (needCacheStorage(srcData, destData)) { - cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); + if (needCacheStorage(srcData, destData)) { + cacheData = cacheMgr.getCacheObject(srcData, destData.getDataStore().getScope()); - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); - cmd.setCacheTO(cacheData.getTO()); - EndPoint ep = selector.select(srcData, destData); - Answer answer = ep.sendMessage(cmd); + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); + cmd.setCacheTO(cacheData.getTO()); + EndPoint ep = selector.select(srcData, destData); + answer = ep.sendMessage(cmd); + } else { + CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); + EndPoint ep = selector.select(srcData, destData); + answer = ep.sendMessage(cmd); + } + // clean up cache entry in case of failure + if (answer == null || !answer.getResult()) { + if (cacheData != null) { + cacheMgr.deleteCacheObject(cacheData); + } + } return answer; - } else { - CopyCommand cmd = new CopyCommand(srcData.getTO(), destData.getTO(), _backupsnapshotwait); - EndPoint ep = selector.select(srcData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; - } } catch (Exception e) { s_logger.debug("copy snasphot failed: " + e.toString()); if (cacheData != null) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index de57dd7f2fe..2b698fb3d61 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -77,13 +77,14 @@ public class DefaultEndPointSelector implements EndPointSelector { protected boolean moveBetweenCacheAndImage(DataStore srcStore, DataStore destStore) { DataStoreRole srcRole = srcStore.getRole(); DataStoreRole destRole = destStore.getRole(); - if (srcRole == DataStoreRole.Image && destRole == DataStoreRole.ImageCache) { + if (srcRole == DataStoreRole.Image && destRole == DataStoreRole.ImageCache || + srcRole == DataStoreRole.ImageCache && destRole == DataStoreRole.Image) { return true; } else { return false; } } - + protected boolean moveBetweenImages(DataStore srcStore, DataStore destStore) { DataStoreRole srcRole = srcStore.getRole(); DataStoreRole destRole = destStore.getRole(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index a2a9045b51f..4a3fd3f2e05 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -403,13 +403,21 @@ public class VolumeObject implements VolumeInfo { vol.setPoolId(this.getDataStore().getId()); volumeDao.update(vol.getId(), vol); } - } else if (this.dataStore.getRole() == DataStoreRole.Image) { + } else { + // image store or imageCache store if (answer instanceof DownloadAnswer) { DownloadAnswer dwdAnswer = (DownloadAnswer) answer; VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); volStore.setInstallPath(dwdAnswer.getInstallPath()); volStore.setChecksum(dwdAnswer.getCheckSum()); this.volumeStoreDao.update(volStore.getId(), volStore); + } else if (answer instanceof CopyCmdAnswer ){ + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer; + VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); + VolumeObjectTO newVol = (VolumeObjectTO) cpyAnswer.getNewData(); + volStore.setInstallPath(newVol.getPath()); + volStore.setSize(newVol.getSize()); + this.volumeStoreDao.update(volStore.getId(), volStore); } } } catch (RuntimeException ex) { From 01e36538aadb88d4d95dbe917ad48d15e6cd6d84 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 21 May 2013 22:18:35 -0700 Subject: [PATCH 236/303] Fix a bug in creating volume path in copy command. --- .../resource/XenServerStorageProcessor.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 4a623fc1271..29ffa4e26b7 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -96,7 +96,7 @@ public class XenServerStorageProcessor implements StorageProcessor { public XenServerStorageProcessor(CitrixResourceBase resource) { this.hypervisorResource = resource; } - + @Override public AttachAnswer attachIso(AttachCommand cmd) { DiskTO disk = cmd.getDisk(); @@ -161,7 +161,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new AttachAnswer(e.toString()); } } - + @Override public AttachAnswer attachVolume(AttachCommand cmd) { String vmName = cmd.getVmName(); @@ -236,7 +236,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new AttachAnswer(msg); } } - + @Override public Answer dettachIso(DettachCommand cmd) { DiskTO disk = cmd.getDisk(); @@ -298,7 +298,7 @@ public class XenServerStorageProcessor implements StorageProcessor { String msg = "Failed to dettach volume" + " for uuid: " + data.getPath() + " due to " + e.getMessage(); s_logger.warn(msg, e); return new DettachAnswer(msg); - } + } } @@ -330,7 +330,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new DettachAnswer("You attempted an operation that requires PV drivers to be installed on the VM. Please install them by inserting xen-pv-drv.iso."); } - + // Look up all VBDs for this VDI Set vbds = vdi.getVBDs(conn); @@ -356,7 +356,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new DettachAnswer("Failed dettach volume: " + data.getPath() + ", due to " + e.toString()); } } - + protected SR getSRByNameLabel(Connection conn, String nameLabel) throws BadServerResponse, XenAPIException, XmlRpcException { Set srs = SR.getByNameLabel(conn, nameLabel); @@ -431,7 +431,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CreateObjectAnswer(details); } - + @Override public Answer deleteVolume(DeleteCommand cmd) { DataTO volume = cmd.getData(); @@ -507,7 +507,7 @@ public class XenServerStorageProcessor implements StorageProcessor { throw new CloudRuntimeException("Unable to create NFS SR " + pool.toString(), e); } } - + protected SR getIscsiSR(Connection conn, StorageFilerTO pool) { synchronized (pool.getUuid().intern()) { Map deviceConfig = new HashMap(); @@ -831,7 +831,7 @@ public class XenServerStorageProcessor implements StorageProcessor { NfsTO srcImageStore = (NfsTO)srcStore; TemplateObjectTO srcTemplate = (TemplateObjectTO)srcData; String storeUrl = srcImageStore.getUrl(); - + URI uri = new URI(storeUrl); String tmplpath = uri.getHost() + ":" + uri.getPath() + "/" + srcData.getPath(); PrimaryDataStoreTO destStore = (PrimaryDataStoreTO)destData.getDataStore(); @@ -994,7 +994,7 @@ public class XenServerStorageProcessor implements StorageProcessor { } // Create a SR for the volume UUID folder - secondaryStorage = hypervisorResource.createNfsSRbyURI(conn, new URI(nfsStore.getUrl() + destVolume.getPath()), false); + secondaryStorage = hypervisorResource.createNfsSRbyURI(conn, new URI(nfsStore.getUrl() + File.separator + destVolume.getPath()), false); // Look up the volume on the source primary storage pool VDI srcVdi = getVDIbyUuid(conn, srcVolume.getPath()); // Copy the volume to secondary storage @@ -1343,7 +1343,7 @@ public class XenServerStorageProcessor implements StorageProcessor { return new CopyCmdAnswer(details); } - + @Override public Answer createTemplateFromVolume(CopyCommand cmd) { Connection conn = this.hypervisorResource.getConnection(); @@ -1351,13 +1351,13 @@ public class XenServerStorageProcessor implements StorageProcessor { TemplateObjectTO template = (TemplateObjectTO)cmd.getDestTO(); NfsTO destStore = (NfsTO)cmd.getDestTO().getDataStore(); int wait = cmd.getWait(); - + String secondaryStoragePoolURL = destStore.getUrl(); String volumeUUID = volume.getPath(); - + String userSpecifiedName = template.getName(); - - + + String details = null; SR tmpltSR = null; boolean result = false; @@ -1454,7 +1454,7 @@ public class XenServerStorageProcessor implements StorageProcessor { String snapshotInstallPath = snapshot.getPath(); int index = snapshotInstallPath.lastIndexOf(File.separator); String snapshotName = snapshotInstallPath.substring(index + 1); - + if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) { snapshotInstallPath = snapshotInstallPath + ".vhd"; } @@ -1491,7 +1491,7 @@ public class XenServerStorageProcessor implements StorageProcessor { DataStoreTO store = snapshot.getDataStore(); if (store.getRole() == DataStoreRole.Primary) { Connection conn = this.hypervisorResource.getConnection(); - VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath()); + VDI snapshotVdi = getVDIbyUuid(conn, snapshot.getPath()); if (snapshotVdi == null) { return new Answer(null); } From 5af888c67a44fa583890ba04c476d2c2cea0ece3 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 22 May 2013 13:37:44 -0700 Subject: [PATCH 237/303] add image format in volumevo --- api/src/com/cloud/storage/Storage.java | 13 +- api/src/com/cloud/storage/Volume.java | 1 + .../datastore/db/VolumeDataStoreVO.java | 12 - .../cloudstack/storage/to/VolumeObjectTO.java | 20 +- .../src/com/cloud/storage/VolumeVO.java | 11 + .../cloudstack/storage/test/SnapshotTest.java | 24 +- .../cloudstack/storage/test/VolumeTest.java | 32 +- .../storage/test/VolumeTestVmware.java | 32 +- .../storage/test/volumeServiceTest.java | 15 +- .../storage/volume/db/VolumeDao2.java | 82 ---- .../storage/volume/db/VolumeDao2Impl.java | 440 ------------------ .../storage/volume/db/VolumeVO.java | 418 ----------------- .../storage/volume/VolumeObject.java | 6 + .../com/cloud/storage/VolumeManagerImpl.java | 46 +- .../resource/NfsSecondaryStorageResource.java | 2 +- setup/db/db/schema-410to420.sql | 2 + 16 files changed, 109 insertions(+), 1047 deletions(-) delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java diff --git a/api/src/com/cloud/storage/Storage.java b/api/src/com/cloud/storage/Storage.java index c130fe222bf..c50bd7e7e87 100755 --- a/api/src/com/cloud/storage/Storage.java +++ b/api/src/com/cloud/storage/Storage.java @@ -21,13 +21,13 @@ import java.util.List; public class Storage { public static enum ImageFormat { - QCOW2(true, true, false), - RAW(false, false, false), - VHD(true, true, true), - ISO(false, false, false), + QCOW2(true, true, false, "qcow2"), + RAW(false, false, false, "raw"), + VHD(true, true, true, "vhd"), + ISO(false, false, false, "iso"), OVA(true, true, true, "ova"), - BAREMETAL(false, false, false), - TAR(false, false, false); + BAREMETAL(false, false, false, "BAREMETAL"), + TAR(false, false, false, "tar"); private final boolean thinProvisioned; private final boolean supportSparse; @@ -66,6 +66,7 @@ public class Storage { return fileExtension; } + } public static enum FileSystem { diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 4903594f0af..5d11ba9ed0d 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -173,4 +173,5 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba * @param reserv */ void setReservationId(String reserv); + Storage.ImageFormat getFormat(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index c722bbf11fd..2d72922d7dd 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -97,9 +97,6 @@ public class VolumeDataStoreVO implements StateObject, StateDao { - - List findDetachedByAccount(long accountId); - - List findByAccount(long accountId); - - Pair getCountAndTotalByPool(long poolId); - - Pair getNonDestroyedCountAndTotalByPool(long poolId); - - List findByInstance(long id); - - List findByInstanceAndType(long id, VolumeType vType); - - List findByInstanceIdDestroyed(long vmId); - - List findByAccountAndPod(long accountId, long podId); - - List findByTemplateAndZone(long templateId, long zoneId); - - void deleteVolumesByInstance(long instanceId); - - void attachVolume(long volumeId, long vmId, long deviceId); - - void detachVolume(long volumeId); - - boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId); - - List findCreatedByInstance(long id); - - List findByPoolId(long poolId); - - List findByInstanceAndDeviceId(long instanceId, long deviceId); - - List findUsableVolumesForInstance(long instanceId); - - Long countAllocatedVolumesForAccount(long accountId); - - HypervisorType getHypervisorType(long volumeId); - - List listVolumesToBeDestroyed(); - - ImageFormat getImageFormat(Long volumeId); - - List findReadyRootVolumesByInstance(long instanceId); - - List listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId); - - VolumeVO allocVolume(long size, VolumeType type, String volName, Long templateId); - - VolumeVO findByVolumeIdAndPoolId(long volumeId, long poolId); -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java deleted file mode 100644 index d8497e2f3da..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeDao2Impl.java +++ /dev/null @@ -1,440 +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.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import javax.ejb.Local; -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; -import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; -import org.apache.cloudstack.storage.volume.VolumeEvent; - -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Volume; -import com.cloud.tags.dao.ResourceTagDao; -import com.cloud.tags.dao.ResourceTagsDaoImpl; -import com.cloud.utils.Pair; - -import com.cloud.utils.db.DB; -import com.cloud.utils.db.GenericDaoBase; -import com.cloud.utils.db.GenericSearchBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.Transaction; -import com.cloud.utils.db.UpdateBuilder; -import com.cloud.utils.exception.CloudRuntimeException; - -@Local(value = VolumeDao2.class) -@Component -public class VolumeDao2Impl extends GenericDaoBase implements VolumeDao2 { - private static final Logger s_logger = Logger.getLogger(VolumeDao2Impl.class); - protected final SearchBuilder DetachedAccountIdSearch; - protected final SearchBuilder TemplateZoneSearch; - protected final GenericSearchBuilder TotalSizeByPoolSearch; - protected final GenericSearchBuilder ActiveTemplateSearch; - protected final SearchBuilder InstanceStatesSearch; - protected final SearchBuilder AllFieldsSearch; - protected GenericSearchBuilder CountByAccount; - @Inject ResourceTagDao _tagsDao = null; - protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?"; - protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?"; - - private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? " - + " AND pool.pod_id = ? AND pool.cluster_id = ? " + " GROUP BY pool.id ORDER BY 2 ASC "; - - @Override - public List findDetachedByAccount(long accountId) { - SearchCriteria sc = DetachedAccountIdSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("destroyed", Volume.State.Destroy); - return listBy(sc); - } - - @Override - public List findByAccount(long accountId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("state", Volume.State.Ready); - return listBy(sc); - } - - @Override - public List findByInstance(long id) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", id); - return listBy(sc); - } - - @Override - public List findByInstanceAndDeviceId(long instanceId, long deviceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - sc.setParameters("deviceId", deviceId); - return listBy(sc); - } - - @Override - public List findByPoolId(long poolId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("poolId", poolId); - sc.setParameters("notDestroyed", Volume.State.Destroy); - sc.setParameters("vType", new RootDisk().toString()); - return listBy(sc); - } - - @Override - public List findCreatedByInstance(long id) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", id); - sc.setParameters("state", Volume.State.Ready); - return listBy(sc); - } - - @Override - public List findUsableVolumesForInstance(long instanceId) { - SearchCriteria sc = InstanceStatesSearch.create(); - sc.setParameters("instance", instanceId); - sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated); - - return listBy(sc); - } - - @Override - public List findByInstanceAndType(long id, VolumeType vType) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", id); - sc.setParameters("vType", vType.toString()); - return listBy(sc); - } - - @Override - public List findByInstanceIdDestroyed(long vmId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", vmId); - sc.setParameters("destroyed", Volume.State.Destroy); - return listBy(sc); - } - - @Override - public List findReadyRootVolumesByInstance(long instanceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - sc.setParameters("state", Volume.State.Ready); - sc.setParameters("vType", new RootDisk().toString()); - return listBy(sc); - } - - @Override - public List findByAccountAndPod(long accountId, long podId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("pod", podId); - sc.setParameters("state", Volume.State.Ready); - - return listIncludingRemovedBy(sc); - } - - @Override - public List findByTemplateAndZone(long templateId, long zoneId) { - SearchCriteria sc = TemplateZoneSearch.create(); - sc.setParameters("template", templateId); - sc.setParameters("zone", zoneId); - - return listIncludingRemovedBy(sc); - } - - @Override - public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) { - SearchCriteria sc = ActiveTemplateSearch.create(); - sc.setParameters("template", templateId); - sc.setParameters("pool", poolId); - - List results = customSearchIncludingRemoved(sc, null); - assert results.size() > 0 : "How can this return a size of " + results.size(); - - return results.get(0) > 0; - } - - @Override - public void deleteVolumesByInstance(long instanceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - expunge(sc); - } - - @Override - public void attachVolume(long volumeId, long vmId, long deviceId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setInstanceId(vmId); - volume.setDeviceId(deviceId); - volume.setUpdated(new Date()); - volume.setAttached(new Date()); - update(volumeId, volume); - } - - @Override - public void detachVolume(long volumeId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setInstanceId(null); - volume.setDeviceId(null); - volume.setUpdated(new Date()); - volume.setAttached(null); - update(volumeId, volume); - } - - @Override - @DB - public HypervisorType getHypervisorType(long volumeId) { - /* lookup from cluster of pool */ - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - - try { - String sql = SELECT_HYPERTYPE_FROM_VOLUME; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, volumeId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { - return HypervisorType.getType(rs.getString(1)); - } - return HypervisorType.None; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + SELECT_HYPERTYPE_FROM_VOLUME, e); - } - } - - @Override - public ImageFormat getImageFormat(Long volumeId) { - HypervisorType type = getHypervisorType(volumeId); - if (type.equals(HypervisorType.KVM)) { - return ImageFormat.QCOW2; - } else if (type.equals(HypervisorType.XenServer)) { - return ImageFormat.VHD; - } else if (type.equals(HypervisorType.VMware)) { - return ImageFormat.OVA; - } else { - s_logger.warn("Do not support hypervisor " + type.toString()); - return null; - } - } - - protected VolumeDao2Impl() { - AllFieldsSearch = createSearchBuilder(); - AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); - AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); - AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ); - AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ); - AllFieldsSearch.and("deviceId", AllFieldsSearch.entity().getDeviceId(), Op.EQ); - AllFieldsSearch.and("poolId", AllFieldsSearch.entity().getPoolId(), Op.EQ); - AllFieldsSearch.and("vType", AllFieldsSearch.entity().getVolumeType(), Op.EQ); - AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); - AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ); - AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ); - AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ); - AllFieldsSearch.done(); - - DetachedAccountIdSearch = createSearchBuilder(); - DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ); - DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ); - DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL); - DetachedAccountIdSearch.done(); - - TemplateZoneSearch = createSearchBuilder(); - TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ); - TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ); - TemplateZoneSearch.done(); - - TotalSizeByPoolSearch = createSearchBuilder(SumCount.class); - TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize()); - TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[]) null); - TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ); - TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL); - TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ); - TotalSizeByPoolSearch.done(); - - ActiveTemplateSearch = createSearchBuilder(Long.class); - ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ); - ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ); - ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL); - ActiveTemplateSearch.select(null, Func.COUNT, null); - ActiveTemplateSearch.done(); - - InstanceStatesSearch = createSearchBuilder(); - InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ); - InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN); - InstanceStatesSearch.done(); - - CountByAccount = createSearchBuilder(Long.class); - CountByAccount.select(null, Func.COUNT, null); - CountByAccount.and("account", CountByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); - CountByAccount.and("state", CountByAccount.entity().getState(), SearchCriteria.Op.NIN); - CountByAccount.done(); - } - - @Override - @DB(txn = false) - public Pair getCountAndTotalByPool(long poolId) { - SearchCriteria sc = TotalSizeByPoolSearch.create(); - sc.setParameters("poolId", poolId); - List results = customSearch(sc, null); - SumCount sumCount = results.get(0); - return new Pair(sumCount.count, sumCount.sum); - } - - @Override - public Long countAllocatedVolumesForAccount(long accountId) { - SearchCriteria sc = CountByAccount.create(); - sc.setParameters("account", accountId); - sc.setParameters("state", Volume.State.Destroy); - return customSearch(sc, null).get(0); - } - - public static class SumCount { - public long sum; - public long count; - - public SumCount() { - } - } - - @Override - public List listVolumesToBeDestroyed() { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("state", Volume.State.Destroy); - - return listBy(sc); - } - - @Override - public boolean updateState(Volume.State currentState, Volume.Event event, Volume.State nextState, VolumeVO vo, Object data) { - - Long oldUpdated = vo.getUpdatedCount(); - Date oldUpdatedTime = vo.getUpdated(); - - SearchCriteria sc = AllFieldsSearch.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, "updated", new Date()); - - int rows = update((VolumeVO) vo, sc); - if (rows == 0 && s_logger.isDebugEnabled()) { - VolumeVO dbVol = findByIdIncludingRemoved(vo.getId()); - if (dbVol != null) { - StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") - .append(dbVol.getUpdated()); - str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()) - .append("; updatedTime=").append(vo.getUpdated()); - str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) - .append("; updatedTime=").append(oldUpdatedTime); - } else { - s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore"); - } - } - return rows > 0; - } - - @Override - public List listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - try { - String sql = ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, accountId); - pstmt.setLong(2, dcId); - pstmt.setLong(3, podId); - pstmt.setLong(4, clusterId); - - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(rs.getLong(1)); - } - return result; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); - } - } - - @Override - @DB(txn = false) - public Pair getNonDestroyedCountAndTotalByPool(long poolId) { - SearchCriteria sc = TotalSizeByPoolSearch.create(); - sc.setParameters("poolId", poolId); - sc.setParameters("state", Volume.State.Destroy); - List results = customSearch(sc, null); - SumCount sumCount = results.get(0); - return new Pair(sumCount.count, sumCount.sum); - } - - @Override - @DB - public boolean remove(Long id) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - VolumeVO entry = findById(id); - if (entry != null) { - _tagsDao.removeByIdAndType(id, TaggedResourceType.Volume); - } - boolean result = super.remove(id); - txn.commit(); - return result; - } - - @Override - @DB - public VolumeVO allocVolume(long size, VolumeType type, String volName, Long templateId) { - VolumeVO vol = new VolumeVO(size, type.toString(), volName, templateId); - vol = this.persist(vol); - return vol; - } - - @Override - public VolumeVO findByVolumeIdAndPoolId(long volumeId, long poolId) { - SearchCriteriaService sc = SearchCriteria2.create(VolumeVO.class); - sc.addAnd(sc.getEntity().getId(), Op.EQ, volumeId); - sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId); - return sc.find(); - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java deleted file mode 100644 index 831022455c9..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/VolumeVO.java +++ /dev/null @@ -1,418 +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 java.util.UUID; - -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.TableGenerator; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; - -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Volume; -import com.cloud.utils.NumbersUtil; -import com.cloud.utils.db.GenericDao; -import com.cloud.utils.fsm.StateObject; - -@Entity -@Table(name = "volumes") -public class VolumeVO implements Identity, StateObject { - @Id - @TableGenerator(name = "volume_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "volume_seq", allocationSize = 1) - @GeneratedValue(strategy = GenerationType.TABLE) - @Column(name = "id") - long id; - - @Column(name = "name") - String name; - - @Column(name = "pool_id") - Long poolId; - - @Column(name = "last_pool_id") - Long lastPoolId; - - @Column(name = "account_id") - long accountId; - - @Column(name = "domain_id") - long domainId; - - @Column(name = "instance_id") - Long instanceId = null; - - @Column(name = "device_id") - Long deviceId = null; - - @Column(name = "size") - long size; - - @Column(name = "folder") - String folder; - - @Column(name = "path") - String path; - - @Column(name = "pod_id") - Long podId; - - @Column(name = "created") - Date created; - - @Column(name = "attached") - @Temporal(value = TemporalType.TIMESTAMP) - Date attached; - - @Column(name = "data_center_id") - long dataCenterId; - - @Column(name = "host_ip") - String hostip; - - @Column(name = "disk_offering_id") - long diskOfferingId; - - @Column(name = "template_id") - Long templateId; - - @Column(name = "first_snapshot_backup_uuid") - String firstSnapshotBackupUuid; - - @Column(name = "volume_type") - String volumeType = "UNKNOWN"; - - @Column(name = "pool_type") - @Enumerated(EnumType.STRING) - StoragePoolType poolType; - - @Column(name = "disk_type") - DiskFormat diskType; - - @Column(name = GenericDao.REMOVED_COLUMN) - Date removed; - - @Column(name = "updated") - @Temporal(value = TemporalType.TIMESTAMP) - Date updated; - - @Column(name = "update_count", updatable = true, nullable = false) - protected long updatedCount; // This field should be updated everytime the - // state is updated. There's no set method in - // the vo object because it is done with in the - // dao code. - - @Column(name = "recreatable") - boolean recreatable; - - @Column(name = "state") - @Enumerated(value = EnumType.STRING) - private Volume.State state; - - @Column(name = "chain_info") - String chainInfo; - - @Column(name = "uuid") - String uuid; - - // Real Constructor - public VolumeVO(long size, String type, String name, Long templateId) { - this.volumeType = type; - this.size = size; - this.name = name; - this.templateId = templateId; - this.uuid = UUID.randomUUID().toString(); - this.state = Volume.State.Allocated; - } - - // Copy Constructor - public VolumeVO(VolumeVO that) { - this(that.getSize(), that.getVolumeType(), that.getName(), that.getTemplateId()); - this.recreatable = that.isRecreatable(); - this.state = that.getState(); - - this.size = that.getSize(); - this.diskOfferingId = that.getDiskOfferingId(); - this.poolId = that.getPoolId(); - this.attached = that.getAttached(); - this.chainInfo = that.getChainInfo(); - this.templateId = that.getTemplateId(); - this.deviceId = that.getDeviceId(); - this.uuid = UUID.randomUUID().toString(); - } - - public long getUpdatedCount() { - return this.updatedCount; - } - - public void incrUpdatedCount() { - this.updatedCount++; - } - - public void decrUpdatedCount() { - this.updatedCount--; - } - - public boolean isRecreatable() { - return recreatable; - } - - public void setRecreatable(boolean recreatable) { - this.recreatable = recreatable; - } - - public long getId() { - return id; - } - - public Long getPodId() { - return podId; - } - - public long getDataCenterId() { - return dataCenterId; - } - - public String getName() { - return name; - } - - public long getAccountId() { - return accountId; - } - - public void setPoolType(StoragePoolType poolType) { - this.poolType = poolType; - } - - public StoragePoolType getPoolType() { - return poolType; - } - - public long getDomainId() { - return domainId; - } - - public String getFolder() { - return folder; - } - - public String getPath() { - return path; - } - - protected VolumeVO() { - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public Long getInstanceId() { - return instanceId; - } - - public Long getDeviceId() { - return deviceId; - } - - public void setDeviceId(Long deviceId) { - this.deviceId = deviceId; - } - - public String getVolumeType() { - return volumeType; - } - - public void setName(String name) { - this.name = name; - } - - public void setFolder(String folder) { - this.folder = folder; - } - - public void setAccountId(long accountId) { - this.accountId = accountId; - } - - public void setDomainId(long domainId) { - this.domainId = domainId; - } - - public void setInstanceId(Long instanceId) { - this.instanceId = instanceId; - } - - public void setPath(String path) { - this.path = path; - } - - public String getHostIp() { - return hostip; - } - - public void setHostIp(String hostip) { - this.hostip = hostip; - } - - public void setPodId(Long podId) { - this.podId = podId; - } - - public void setDataCenterId(long dataCenterId) { - this.dataCenterId = dataCenterId; - } - - public void setVolumeType(String type) { - volumeType = type; - } - - public Date getCreated() { - return created; - } - - public Date getRemoved() { - return removed; - } - - public void setRemoved(Date removed) { - this.removed = removed; - } - - public long getDiskOfferingId() { - return diskOfferingId; - } - - public void setDiskOfferingId(long diskOfferingId) { - this.diskOfferingId = diskOfferingId; - } - - public Long getTemplateId() { - return templateId; - } - - public void setTemplateId(Long templateId) { - this.templateId = templateId; - } - - public String getFirstSnapshotBackupUuid() { - return firstSnapshotBackupUuid; - } - - public void setFirstSnapshotBackupUuid(String firstSnapshotBackupUuid) { - this.firstSnapshotBackupUuid = firstSnapshotBackupUuid; - } - - public Long getPoolId() { - return poolId; - } - - public void setPoolId(Long poolId) { - this.poolId = poolId; - } - - public Date getUpdated() { - return updated; - } - - @Override - public Volume.State getState() { - return state; - } - - public void setUpdated(Date updated) { - this.updated = updated; - } - - @Override - public String toString() { - return new StringBuilder("Vol[").append(id).append("|vm=").append(instanceId).append("|").append(volumeType).append("]").toString(); - } - - public Date getAttached() { - return this.attached; - } - - public void setAttached(Date attached) { - this.attached = attached; - } - - public String getChainInfo() { - return this.chainInfo; - } - - public void setChainInfo(String chainInfo) { - this.chainInfo = chainInfo; - } - - public Long getLastPoolId() { - return this.lastPoolId; - } - - public void setLastPoolId(Long poolId) { - this.lastPoolId = poolId; - } - - @Override - public int hashCode() { - return NumbersUtil.hash(id); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof VolumeVO) { - return id == ((VolumeVO) obj).id; - } else { - return false; - } - } - - @Override - public String getUuid() { - return this.uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public DiskFormat getDiskType() { - return diskType; - } - - public void setDiskType(DiskFormat type) { - diskType = type; - } - -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 4a3fd3f2e05..da5e80ba6c0 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -38,6 +38,7 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; @@ -429,4 +430,9 @@ public class VolumeObject implements VolumeInfo { this.processEvent(event); } + + @Override + public ImageFormat getFormat() { + return this.volumeVO.getFormat(); + } } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 38f995930b2..9af53ee73f0 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -504,6 +504,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { newVol.setDeviceId(oldVol.getDeviceId()); newVol.setInstanceId(oldVol.getInstanceId()); newVol.setRecreatable(oldVol.isRecreatable()); + newVol.setFormat(oldVol.getFormat()); return _volsDao.persist(newVol); } @@ -690,6 +691,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { s_logger.debug("create volume failed: " + result.getResult()); throw new CloudRuntimeException("create volume failed:" + result.getResult()); } + + UsageEventVO usageEvent = new UsageEventVO( EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), @@ -732,7 +735,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setUpdated(new Date()); volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller .getDomainId()); - + volume.setFormat(ImageFormat.valueOf(format)); volume = _volsDao.persist(volume); try { stateTransitTo(volume, Event.UploadRequested); @@ -979,6 +982,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { volume.setDisplayVolume(displayVolumeEnabled); if (parentVolume != null) { volume.setTemplateId(parentVolume.getTemplateId()); + volume.setFormat(parentVolume.getFormat()); } else { volume.setTemplateId(null); } @@ -1358,7 +1362,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } else { vol.setDeviceId(1l); } - + + vol.setFormat(this.getSupportedImageFormatForCluster(vm.getHypervisorType())); vol = _volsDao.persist(vol); // Save usage event and update resource count for user vm volumes @@ -1388,6 +1393,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(), owner.getDomainId(), owner.getId(), offering.getId(), size); + vol.setFormat(this.getSupportedImageFormatForCluster(template.getHypervisorType())); if (vm != null) { vol.setInstanceId(vm.getId()); } @@ -1427,17 +1433,15 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return toDiskProfile(vol, offering); } - private String getSupportedImageFormatForCluster(Long clusterId) { - ClusterVO cluster = ApiDBUtils.findClusterById(clusterId); - - if (cluster.getHypervisorType() == HypervisorType.XenServer) { - return "vhd"; - } else if (cluster.getHypervisorType() == HypervisorType.KVM) { - return "qcow2"; - } else if (cluster.getHypervisorType() == HypervisorType.VMware) { - return "ova"; - } else if (cluster.getHypervisorType() == HypervisorType.Ovm) { - return "raw"; + private ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) { + if (hyperType == HypervisorType.XenServer) { + return ImageFormat.VHD; + } else if (hyperType == HypervisorType.KVM) { + return ImageFormat.QCOW2; + } else if (hyperType == HypervisorType.VMware) { + return ImageFormat.OVA; + } else if (hyperType == HypervisorType.Ovm) { + return ImageFormat.RAW; } else { return null; } @@ -1446,16 +1450,14 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { private VolumeInfo copyVolume(StoragePoolVO rootDiskPool , VolumeInfo volume, VMInstanceVO vm, VMTemplateVO rootDiskTmplt, DataCenterVO dcVO, HostPodVO pod, DiskOfferingVO diskVO, ServiceOfferingVO svo, HypervisorType rootDiskHyperType) throws NoTransitionException { - VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(volume.getDataStore().getId(), volume.getId()); - if (!volStoreVO + + if (!volume .getFormat() - .getFileExtension() .equals( - getSupportedImageFormatForCluster(rootDiskPool - .getClusterId()))) { + getSupportedImageFormatForCluster(rootDiskHyperType))) { throw new InvalidParameterValueException( "Failed to attach volume to VM since volumes format " - + volStoreVO.getFormat() + + volume.getFormat() .getFileExtension() + " is not compatible with the vm hypervisor type"); } @@ -1502,7 +1504,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { ResourceType.primary_storage, new Long(volume.getSize())); } } - return vol; + + VolumeVO volVO = this._volsDao.findById(vol.getId()); + volVO.setFormat(this.getSupportedImageFormatForCluster(rootDiskHyperType)); + this._volsDao.update(volVO.getId(), volVO); + return this.volFactory.getVolume(volVO.getId()); } private boolean needMoveVolume(VolumeVO rootVolumeOfVm, VolumeInfo volume) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 8dca6f52206..eee7e2722a3 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -290,7 +290,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if ( srcData.getObjectType() == DataObjectType.TEMPLATE){ extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension(); } else{ - extension = ((VolumeObjectTO)srcData).getDiskType().toString().toLowerCase(); + extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension(); } String templateName = UUID.randomUUID().toString(); diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index aecb93884ff..d33c070f84f 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -388,6 +388,8 @@ ALTER TABLE `cloud`.`user_vm_details` ADD COLUMN `display_detail` tinyint(1) NOT ALTER TABLE `cloud`.`volumes` ADD COLUMN `display_volume` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should volume be displayed to the end user'; +ALTER TABLE `cloud`.`volumes` ADD COLUMN `format` varchar(255) COMMENT 'volume format'; + ALTER TABLE `cloud`.`networks` ADD COLUMN `display_network` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should network be displayed to the end user'; ALTER TABLE `cloud`.`nics` ADD COLUMN `display_nic` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should nic be displayed to the end user'; From eb0a7489b4bd5fb4bccdfa3c5b1299e6c05381d7 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 22 May 2013 13:47:09 -0700 Subject: [PATCH 238/303] remove format from volume_store table --- setup/db/db/schema-410to420.sql | 1 - 1 file changed, 1 deletion(-) diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index d33c070f84f..babe25e4d69 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -204,7 +204,6 @@ CREATE TABLE `cloud`.`volume_store_ref` ( `install_path` varchar(255), `url` varchar(255), `state` varchar(255) NOT NULL, - `format` varchar(32) NOT NULL COMMENT 'format for the volume', `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', `update_count` bigint unsigned, `updated` datetime, From 039098469a445cefb7d45177872f8d886cb6c1ef Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 22 May 2013 14:31:53 -0700 Subject: [PATCH 239/303] CLOUDSTACK-2584: set Format value in CopyCommand. --- .../storage/image/store/TemplateObject.java | 4 ++ .../ObjectInDataStoreManagerImpl.java | 9 +++- .../cloud/template/TemplateManagerImpl.java | 4 +- .../resource/NfsSecondaryStorageResource.java | 41 +++++++++++++++---- .../storage/template/DownloadManagerImpl.java | 3 -- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index feff54ee102..b17fc3df254 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -256,6 +256,10 @@ public class TemplateObject implements TemplateInfo { } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); + } catch (Exception ex){ + s_logger.debug("failed to process event and answer", ex); + objectInStoreMgr.delete(this); + throw new CloudRuntimeException("Failed to process event", ex); } finally{ // in case of OperationFailed, expunge the entry if ( event == ObjectInDataStoreStateMachine.Event.OperationFailed){ diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index f2ec961c6e1..daeaf7cfd0a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -25,6 +25,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; @@ -43,6 +44,7 @@ import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.S3TO; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.storage.dao.SnapshotDao; @@ -136,7 +138,12 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { ts.setTemplateId(obj.getId()); ts.setDataStoreId(dataStore.getId()); ts.setDataStoreRole(dataStore.getRole()); - ts.setInstallPath(TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + String installPath = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId(); + if ( dataStore.getTO() instanceof S3TO ){ + TemplateInfo tmpl = (TemplateInfo)obj; + installPath += "/" + tmpl.getUniqueName(); // for S3, we append template name in the path for template sync since we don't have template.properties there + } + ts.setInstallPath(installPath); ts.setState(ObjectInDataStoreStateMachine.State.Allocated); ts = templateDataStoreDao.persist(ts); break; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 21615c9ee8d..c5e80b01ffe 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1456,7 +1456,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (privateTemplate == null) { Transaction txn = Transaction.currentTxn(); txn.start(); - // template_store_ref entries should have been removed using our DataObject.processEvent command in case of failure. + // template_store_ref entries should have been removed using our DataObject.processEvent command in case of failure, but clean it up here to avoid + // some leftovers which will cause removing template from vm_template table fail. + this._tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); // Remove the template_zone_ref record this._tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); // Remove the template record diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index eee7e2722a3..a7c409df634 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -426,11 +426,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } return new CopyCmdAnswer(""); } - + protected Answer copyFromNfsToImage(CopyCommand cmd) { DataTO destData = cmd.getDestTO(); DataStoreTO destDataStore = destData.getDataStore(); - + if (destDataStore instanceof S3TO) { return copyFromNfsToS3(cmd); } else { @@ -453,7 +453,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S NfsTO destImageStore = (NfsTO)destDataStore; return this.copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore); } - + if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) { return copyFromNfsToImage(cmd); } @@ -625,15 +625,40 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } + private ImageFormat getTemplateFormat(String filePath){ + String ext = null; + int extensionPos = filePath.lastIndexOf('.'); + int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\')); + int i = lastSeparator > extensionPos ? -1 : extensionPos; + if (i > 0 ) { + ext = filePath.substring(i+1); + } + if ( ext != null){ + if ( ext.equalsIgnoreCase("vhd")) + return ImageFormat.VHD; + else if (ext.equalsIgnoreCase("qcow2")) + return ImageFormat.QCOW2; + else if (ext.equalsIgnoreCase("ova")) + return ImageFormat.OVA; + else if (ext.equalsIgnoreCase("tar")) + return ImageFormat.TAR; + else if (ext.equalsIgnoreCase("img")) + return ImageFormat.RAW; + } + + return null; + + } + protected Answer copyFromNfsToS3(CopyCommand cmd) { final DataTO srcData = cmd.getSrcTO(); final DataTO destData = cmd.getDestTO(); DataStoreTO srcDataStore = srcData.getDataStore(); NfsTO srcStore = (NfsTO)srcDataStore; DataStoreTO destDataStore = destData.getDataStore(); - + final S3TO s3 = (S3TO)destDataStore; - + try { final String templatePath = determineStorageTemplatePath( srcStore.getUrl(), srcData.getPath()); @@ -645,14 +670,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S final String bucket = s3.getBucketName(); final File srcFile = _storage.getFile(templatePath); + ImageFormat format = this.getTemplateFormat(templatePath); String key = destData.getPath() + S3Utils.SEPARATOR + srcFile.getName(); putFile(s3, srcFile, bucket, key); - + DataTO retObj = null; if (destData.getObjectType() == DataObjectType.TEMPLATE) { TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(key); newTemplate.setSize(srcFile.length()); + newTemplate.setFormat(format); retObj = newTemplate; } else if (destData.getObjectType() == DataObjectType.VOLUME) { VolumeObjectTO newVol = new VolumeObjectTO(); @@ -660,7 +687,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S newVol.setSize(srcFile.length()); retObj = newVol; } - + return new CopyCmdAnswer(retObj); } catch (Exception e) { s_logger.error("failed to upload" + srcData.getPath(), e); diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index dc08ba668fc..509364b2759 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -697,9 +697,6 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager } else { installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; } - } else if (dstore instanceof S3TO) { - // S3 key has template name inside to help template sync - installPathPrefix = installPathPrefix + File.separator + cmd.getName(); } String user = null; String password = null; From 8a956203d146a7fc6387f69d4fe7943c239f1986 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 22 May 2013 14:32:51 -0700 Subject: [PATCH 240/303] ListImageStores still show those deleted image stores. --- .../com/cloud/api/query/vo/ImageStoreJoinVO.java | 15 +++++++++++++++ setup/db/db/schema-410to420.sql | 1 + 2 files changed, 16 insertions(+) diff --git a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java index 7014e05ad39..ac161afe47d 100644 --- a/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java +++ b/server/src/com/cloud/api/query/vo/ImageStoreJoinVO.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.api.query.vo; +import java.util.Date; + import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; @@ -26,6 +28,8 @@ import javax.persistence.Table; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; +import com.cloud.utils.db.GenericDao; + import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.InternalIdentity; @@ -79,6 +83,8 @@ public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Id @Column(name="detail_value") private String detailValue; + @Column(name=GenericDao.REMOVED_COLUMN) + private Date removed; @Override public long getId() { @@ -189,4 +195,13 @@ public class ImageStoreJoinVO extends BaseViewVO implements InternalIdentity, Id this.role = role; } + public Date getRemoved() { + return removed; + } + + public void setRemoved(Date removed) { + this.removed = removed; + } + + } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index babe25e4d69..5ddf3b65112 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -110,6 +110,7 @@ CREATE VIEW `cloud`.`image_store_view` AS image_store.url, image_store.scope, image_store.role, + image_store.removed, data_center.id data_center_id, data_center.uuid data_center_uuid, data_center.name data_center_name, From 3a14d45410cb56234973473717116b2a40b5dd10 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 22 May 2013 17:49:40 -0700 Subject: [PATCH 241/303] Fix MS startup issue due to removal of VolumeDao2Impl. --- client/tomcatconf/applicationContext.xml.in | 1 - 1 file changed, 1 deletion(-) diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index ba47db3cd94..7552b29c1eb 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -361,7 +361,6 @@ - From b4a996dd421a5fe2b01ddf4e908a242948b82ba2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 22 May 2013 17:50:50 -0700 Subject: [PATCH 242/303] CLOUDSTACK-2635: destroyed snapshots are still showing up from UI. --- .../storage/snapshot/SnapshotManagerImpl.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 142f58e0daa..67b60623a6a 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -288,7 +288,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, throw new InvalidParameterValueException("Volume is not in ready state"); } - + boolean backedUp = false; // does the caller have the authority to act on this volume _accountMgr.checkAccess(UserContext.current().getCaller(), null, true, volume); @@ -351,7 +351,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, /* @Override public void downloadSnapshotsFromSwift(SnapshotVO ss) { - + long volumeId = ss.getVolumeId(); VolumeVO volume = _volsDao.findById(volumeId); Long dcId = volume.getDataCenterId(); @@ -581,7 +581,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, SearchBuilder sb = _snapshotDao.createSearchBuilder(); _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); - sb.and("status", sb.entity().getState(), SearchCriteria.Op.EQ); + sb.and("statusNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); //exclude those Destroyed snapshot, not showing on UI sb.and("volumeId", sb.entity().getVolumeId(), SearchCriteria.Op.EQ); sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE); sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ); @@ -602,13 +602,15 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, if(zoneType != null) { SearchBuilder zoneSb = _dcDao.createSearchBuilder(); - zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); + zoneSb.and("zoneNetworkType", zoneSb.entity().getNetworkType(), SearchCriteria.Op.EQ); sb.join("zoneSb", zoneSb, sb.entity().getDataCenterId(), zoneSb.entity().getId(), JoinBuilder.JoinType.INNER); } - + SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); + sc.setParameters("statusNEQ", Snapshot.State.Destroyed); + if (volumeId != null) { sc.setParameters("volumeId", volumeId); } @@ -624,9 +626,9 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } if(zoneType != null) { - sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); + sc.setJoinParameters("zoneSb", "zoneNetworkType", zoneType); } - + if (name != null) { sc.setParameters("name", "%" + name + "%"); } @@ -925,8 +927,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, return null; } - - + + private boolean hostSupportSnapsthot(HostVO host) { if (host.getHypervisorType() != HypervisorType.KVM) { return true; @@ -944,14 +946,14 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } return false; } - + private boolean supportedByHypervisor(VolumeInfo volume) { StoragePool storagePool = (StoragePool)volume.getDataStore(); ClusterVO cluster = _clusterDao.findById(storagePool.getClusterId()); if (cluster != null && cluster.getHypervisorType() == HypervisorType.Ovm) { throw new InvalidParameterValueException("Ovm won't support taking snapshot"); } - + if (volume.getHypervisorType().equals(HypervisorType.KVM)) { List hosts = _resourceMgr.listAllHostsInCluster(cluster.getId()); if (hosts != null && !hosts.isEmpty()) { @@ -995,7 +997,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, Account snapshotOwner = payload.getAccount(); SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotId, volume.getDataStore()); boolean processed = false; - + try { for (SnapshotStrategy strategy : snapshotStrategies) { if (strategy.canHandle(snapshot)) { @@ -1008,7 +1010,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, throw new CloudRuntimeException("Can't find snapshot strategy to deal with snapshot:" + snapshotId); } postCreateSnapshot(volume.getId(), snapshotId, payload.getSnapshotPolicyId()); - + UsageEventUtils.publishUsageEvent(EventTypes.EVENT_SNAPSHOT_CREATE, snapshot.getAccountId(), snapshot.getDataCenterId(), snapshotId, snapshot.getName(), null, null, volume.getSize(), snapshot.getClass().getName(), snapshot.getUuid()); @@ -1159,7 +1161,7 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, HypervisorType hypervisorType = volume.getHypervisorType(); SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName, (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), hypervisorType); - + SnapshotVO snapshot = _snapshotDao.persist(snapshotVO); if (snapshot == null) { throw new CloudRuntimeException("Failed to create snapshot for volume: " + volume.getId()); From 896095760502595aa43be343dcbf3abf79a98ae2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 10:45:47 -0700 Subject: [PATCH 243/303] CLOUDSTACK-2634:all delta snapshots relating to volume should be created in the same secondary storage as the first snapshot. --- .../storage/snapshot/SnapshotServiceImpl.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 25c283a57e3..5717c179858 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -30,6 +30,7 @@ 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.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; @@ -259,6 +260,22 @@ public class SnapshotServiceImpl implements SnapshotService { } + // if a snapshot has parent snapshot, the new snapshot should be stored in the same store as its parent since + // we are taking delta snapshot + private DataStore findSnapshotImageStore(SnapshotInfo snapshot){ + if ( snapshot.getParent() == null ){ + return dataStoreMgr.getImageStore(snapshot.getDataCenterId()); + } else{ + SnapshotInfo parentSnapshot = snapshot.getParent(); + // Note that DataStore information in parentSnapshot is for primary data store here, we need to + // find the image store where the parent snapshot backup is located + SnapshotDataStoreVO parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); + return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), + parentSnapshotOnBackupStore.getRole()); + } + } + + @Override public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { SnapshotObject snapObj = (SnapshotObject)snapshot; @@ -268,7 +285,7 @@ public class SnapshotServiceImpl implements SnapshotService { snapObj.processEvent(Snapshot.Event.BackupToSecondary); - DataStore imageStore = this.dataStoreMgr.getImageStore(snapshot.getDataCenterId()); + DataStore imageStore = this.findSnapshotImageStore(snapshot); if (imageStore == null) { throw new CloudRuntimeException("can not find an image stores"); } From 755b9311a4599955905afed561797344b3baf688 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 10:49:41 -0700 Subject: [PATCH 244/303] Fix some typo. --- .../CloudStackPrimaryDataStoreDriverImpl.java | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index aad17691f47..e801429fcd6 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -36,16 +36,10 @@ import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CreateObjectCommand; import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.to.SnapshotObjectTO; import org.apache.cloudstack.storage.volume.VolumeObject; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.ManageSnapshotAnswer; -import com.cloud.agent.api.ManageSnapshotCommand; -import com.cloud.agent.api.storage.CreateAnswer; -import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; import com.cloud.agent.api.to.DataObjectType; @@ -54,19 +48,15 @@ import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.dao.HostDao; -import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.ResizeVolumePayload; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; 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.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.vm.DiskProfile; import com.cloud.vm.dao.VMInstanceDao; public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { @@ -82,7 +72,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Inject SnapshotDao snapshotDao; @Inject PrimaryDataStoreDao primaryStoreDao; @Inject SnapshotManager snapshotMgr; - @Inject EndPointSelector epSelecotor; + @Inject EndPointSelector epSelector; @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -118,9 +108,9 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri if (s_logger.isDebugEnabled()) { s_logger.debug("Creating volume: " + volume); } - + CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO()); - EndPoint ep = epSelecotor.select(volume); + EndPoint ep = epSelector.select(volume); Answer answer = ep.sendMessage(cmd); return answer; } @@ -157,7 +147,7 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri CommandResult result = new CommandResult(); try { - EndPoint ep = epSelecotor.select(data); + EndPoint ep = epSelector.select(data); Answer answer = ep.sendMessage(cmd); if (answer != null && !answer.getResult()) { result.setResult(answer.getDetails()); @@ -188,11 +178,11 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri CreateCmdResult result = null; try { DataTO snapshotTO = snapshot.getTO(); - + CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO); - EndPoint ep = this.epSelecotor.select(snapshot); + EndPoint ep = this.epSelector.select(snapshot); Answer answer = ep.sendMessage(cmd); - + result = new CreateCmdResult(null, answer); if (answer != null && !answer.getResult()) { result.setResult(answer.getDetails()); From 4611b515db1368c43787bf9843008e522f9519a0 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 11:02:49 -0700 Subject: [PATCH 245/303] Not passing format to VolumeDataStore due to removal of format column from volume_store_ref. --- .../cloudstack/storage/datastore/db/VolumeDataStoreVO.java | 2 +- server/src/com/cloud/storage/download/DownloadMonitorImpl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index 2d72922d7dd..7e89de44e9e 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -205,7 +205,7 @@ public class VolumeDataStoreVO implements StateObject 2)) { downloadJobExists = true; From 8d08f9b74bbf9bd08ccaa988ec5f458786cbfb72 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 12:05:58 -0700 Subject: [PATCH 246/303] CLOUDSTACK-2655: use ssvm public IP to construct extract url. --- .../subsystem/api/storage/EndPoint.java | 1 + .../cloudstack/storage/test/SnapshotTest.java | 24 +++++++++---------- .../cloudstack/storage/test/VolumeTest.java | 2 +- .../storage/test/VolumeTestVmware.java | 4 ++-- .../storage/test/volumeServiceTest.java | 10 ++++---- .../cloudstack/storage/LocalHostEndpoint.java | 7 ++++++ .../storage/RemoteHostEndPoint.java | 13 +++++++--- .../endpoint/DefaultEndPointSelector.java | 8 +++---- .../storage/upload/UploadMonitorImpl.java | 2 +- 9 files changed, 43 insertions(+), 28 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java index 34cb1395fa5..904ee989f2c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java @@ -24,6 +24,7 @@ import com.cloud.agent.api.Command; public interface EndPoint { public long getId(); public String getHostAddr(); + public String getPublicAddr(); public Answer sendMessage(Command cmd); public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 9b6204da459..503b8d36350 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -266,12 +266,12 @@ public class SnapshotTest extends CloudStackTestNGBase { hosts.add(this.host); Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); - remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(remoteEp); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(remoteEp); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp); Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId()); - + } public DataStore createPrimaryDataStore() { @@ -333,7 +333,7 @@ public class SnapshotTest extends CloudStackTestNGBase { } private VolumeVO createVolume(Long templateId, long dataStoreId) { - + VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); volume.setDataCenterId(this.dcId); volume.setPoolId(dataStoreId); @@ -376,18 +376,18 @@ public class SnapshotTest extends CloudStackTestNGBase { } } AssertJUnit.assertNotNull(newSnapshot); - + LocalHostEndpoint ep = new MockLocalHostEndPoint(); ep.setResource(new MockLocalNfsSecondaryStorageResource()); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); - + //delete snapshot for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { strategy.deleteSnapshot(newSnapshot.getId()); } } - + Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp); } @@ -412,7 +412,7 @@ public class SnapshotTest extends CloudStackTestNGBase { image = imageDataDao.persist(image); return image; } - + @Test public void createVolumeFromSnapshot() { VolumeInfo vol = createCopyBaseImage(); @@ -432,7 +432,7 @@ public class SnapshotTest extends CloudStackTestNGBase { VolumeInfo newVol = this.volFactory.getVolume(volVO.getId()); this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); } - + @Test public void deleteSnapshot() { VolumeInfo vol = createCopyBaseImage(); @@ -445,14 +445,14 @@ public class SnapshotTest extends CloudStackTestNGBase { } } AssertJUnit.assertNotNull(newSnapshot); - + //create another snapshot for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { strategy.deleteSnapshot(newSnapshot.getId()); } } - + } @Test @@ -477,6 +477,6 @@ public class SnapshotTest extends CloudStackTestNGBase { DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); } - - + + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index ab3475f18a1..187d1f548cc 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -247,7 +247,7 @@ public class VolumeTest extends CloudStackTestNGBase { hosts.add(this.host); Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); - RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java index bd597c2c821..9d5555a8d8a 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java @@ -167,7 +167,7 @@ public class VolumeTestVmware extends CloudStackTestNGBase { cluster.setManagedState(ManagedState.Managed); cluster = clusterDao.persist(cluster); clusterId = cluster.getId(); - + //setup vcenter ClusterDetailsVO clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "url", null); this.clusterDetailsDao.persist(clusterDetailVO); @@ -253,7 +253,7 @@ public class VolumeTestVmware extends CloudStackTestNGBase { hosts.add(this.host); Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); - RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress()); + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index b43a107edae..243d3b2028f 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -128,7 +128,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); - + host = hostDao.findByGuid(this.getHostGuid()); if (host != null) { dcId = host.getDataCenterId(); @@ -170,7 +170,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { host.setClusterId(cluster.getId()); host = hostDao.persist(host); - + imageStore = new ImageStoreVO(); imageStore.setName("test"); imageStore.setDataCenterId(dcId); @@ -194,7 +194,7 @@ public class volumeServiceTest extends CloudStackTestNGBase { Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); List eps = new ArrayList(); eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress())); + host.getPrivateIpAddress(), host.getPublicIpAddress())); Mockito.when(selector.selectAll(Mockito.any(DataStore.class))).thenReturn(eps); Mockito.when(selector.select(Mockito.any(DataObject.class))).thenReturn(eps.get(0)); Mockito.when(selector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(eps.get(0)); @@ -219,10 +219,10 @@ public class volumeServiceTest extends CloudStackTestNGBase { image.setCrossZones(true); image.setExtractable(true); - + //image.setImageDataStoreId(storeId); image = imageDataDao.persist(image); - + return image; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 3267de8eef8..1d21b061367 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -33,6 +33,7 @@ import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.resource.ServerResource; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.download.DownloadListener; +import com.cloud.utils.net.NetUtils; public class LocalHostEndpoint implements EndPoint { private ScheduledExecutorService executor; @@ -53,6 +54,12 @@ public class LocalHostEndpoint implements EndPoint { return "127.0.0.0"; } + + @Override + public String getPublicAddr() { + return NetUtils.getDefaultHostIp(); + } + @Override public Answer sendMessage(Command cmd) { if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand)) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 0e88b651098..5b0debba344 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -49,6 +49,7 @@ public class RemoteHostEndPoint implements EndPoint { private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class); private long hostId; private String hostAddress; + private String publicAddress; @Inject AgentManager agentMgr; @Inject @@ -61,14 +62,15 @@ public class RemoteHostEndPoint implements EndPoint { executor = Executors.newScheduledThreadPool(10); } - private void configure(long hostId, String hostAddress) { + private void configure(long hostId, String hostAddress, String publicAddress) { this.hostId = hostId; this.hostAddress = hostAddress; + this.publicAddress = publicAddress; } - public static RemoteHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress) { + public static RemoteHostEndPoint getHypervisorHostEndPoint(long hostId, String hostAddress, String publicAddress) { RemoteHostEndPoint ep = ComponentContext.inject(RemoteHostEndPoint.class); - ep.configure(hostId, hostAddress); + ep.configure(hostId, hostAddress, publicAddress); return ep; } @@ -77,6 +79,11 @@ public class RemoteHostEndPoint implements EndPoint { return this.hostAddress; } + + public String getPublicAddr() { + return this.publicAddress; + } + @Override public long getId() { return this.hostId; diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 2b698fb3d61..9acc1d7a3c8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -144,7 +144,7 @@ public class DefaultEndPointSelector implements EndPointSelector { } return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress()); + host.getPrivateIpAddress(), host.getPublicIpAddress()); } protected EndPoint findEndPointForImageMove(DataStore srcStore, @@ -204,7 +204,7 @@ public class DefaultEndPointSelector implements EndPointSelector { } Collections.shuffle(ssAHosts); HostVO host = ssAHosts.get(0); - return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress()); + return RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), host.getPublicIpAddress()); } private List listUpAndConnectingSecondaryStorageVmHost(Long dcId) { @@ -243,7 +243,7 @@ public class DefaultEndPointSelector implements EndPointSelector { if (store.getScope().getScopeType() == ScopeType.HOST) { HostVO host = hostDao.findById(store.getScope().getScopeId()); endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress())); + host.getPrivateIpAddress(), host.getPublicIpAddress())); } else if (store.getScope().getScopeType() == ScopeType.CLUSTER) { SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getClusterId(), Op.EQ, store.getScope().getScopeId()); @@ -251,7 +251,7 @@ public class DefaultEndPointSelector implements EndPointSelector { List hosts = sc.find(); for (HostVO host : hosts) { endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress())); + host.getPrivateIpAddress(), host.getPublicIpAddress())); } } else { diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 9e6cfeaae3a..202536176a4 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -239,7 +239,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } //Construct actual URL locally now that the symlink exists at SSVM - String extractURL = generateCopyUrl(ep.getHostAddr(), uuid); + String extractURL = generateCopyUrl(ep.getPublicAddr(), uuid); UploadVO vo = _uploadDao.createForUpdate(); vo.setLastUpdated(new Date()); vo.setUploadUrl(extractURL); From 1e21b0b0e8801b7fafd67ca4c9a9bb307567b9ef Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 13:05:01 -0700 Subject: [PATCH 247/303] Handle null host ip from NetUtils.getDefaultHostIp(). --- .../org/apache/cloudstack/storage/LocalHostEndpoint.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index 1d21b061367..c0957916e7d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -57,7 +57,11 @@ public class LocalHostEndpoint implements EndPoint { @Override public String getPublicAddr() { - return NetUtils.getDefaultHostIp(); + String hostIp= NetUtils.getDefaultHostIp(); + if (hostIp != null) + return hostIp; + else + return "127.0.0.0"; } @Override From 4e4112fcecc4f2791ec99b774f81988f8c416d77 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 23 May 2013 13:51:14 -0700 Subject: [PATCH 248/303] fix attach volume for kvm --- developer/pom.xml | 3 ++- .../src/com/cloud/upgrade/DatabaseCreator.java | 7 +++++++ .../kvm/storage/KVMStorageProcessor.java | 4 ++-- .../com/cloud/server/ConfigurationServerImpl.java | 15 +++++++++++++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/developer/pom.xml b/developer/pom.xml index 3dc276adc23..c02ef1691cc 100644 --- a/developer/pom.xml +++ b/developer/pom.xml @@ -156,6 +156,7 @@ ${basedir}/target/db/cloudbridge_offering_alter.sql ${basedir}/developer-prefill.sql + ${basedir}/developer-prefill.sql.override com.cloud.upgrade.DatabaseUpgradeChecker --database=cloud,usage,awsapi @@ -232,4 +233,4 @@ - \ No newline at end of file + diff --git a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java index 9b1be6bc6b6..c97085b6e9e 100755 --- a/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java +++ b/engine/schema/src/com/cloud/upgrade/DatabaseCreator.java @@ -147,6 +147,13 @@ public class DatabaseCreator { databases = arg.substring(arg.lastIndexOf("=") + 1, arg.length()).split(","); } else if (arg.endsWith(".sql")) { sqlFiles.add(arg); + } else if (arg.endsWith(".sql.override")) { + if (fileExists(arg)) { + int index = arg.lastIndexOf(".override"); + String fileToOverride = arg.substring(0, index); + sqlFiles.remove(fileToOverride); + sqlFiles.add(arg); + } } else if (arg.endsWith(".properties")) { if (!dbPropsFile.endsWith("properties.override") && fileExists(arg)) dbPropsFile = arg; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 53a9308a3ac..a03ac697a77 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -680,7 +680,7 @@ public class KVMStorageProcessor implements StorageProcessor { DiskTO disk = cmd.getDisk(); VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); - String vmName = vol.getVmName(); + String vmName = cmd.getVmName(); try { Connect conn = LibvirtConnection.getConnectionByVmName(vmName); KVMStoragePool primary = storagePoolMgr.getStoragePool( @@ -714,7 +714,7 @@ public class KVMStorageProcessor implements StorageProcessor { DiskTO disk = cmd.getDisk(); VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); - String vmName = vol.getVmName(); + String vmName = cmd.getVmName(); try { Connect conn = LibvirtConnection.getConnectionByVmName(vmName); KVMStoragePool primary = storagePoolMgr.getStoragePool( diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index bc52e9a881c..98f1c964408 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -224,9 +224,20 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } String hostIpAdr = NetUtils.getDefaultHostIp(); + boolean needUpdateHostIp = true; if (hostIpAdr != null) { - _configDao.update(Config.ManagementHostIPAdr.key(), Config.ManagementHostIPAdr.getCategory(), hostIpAdr); - s_logger.debug("ConfigurationServer saved \"" + hostIpAdr + "\" as host."); + Boolean devel = Boolean.valueOf(_configDao.getValue("developer")); + if (devel) { + String value = _configDao.getValue(Config.ManagementHostIPAdr.key()); + if (value != null) { + needUpdateHostIp = false; + } + } + + if (needUpdateHostIp) { + _configDao.update(Config.ManagementHostIPAdr.key(), Config.ManagementHostIPAdr.getCategory(), hostIpAdr); + s_logger.debug("ConfigurationServer saved \"" + hostIpAdr + "\" as host."); + } } // generate a single sign-on key From 8f6eb26e38b221e4a38345f29ca5ce1ce25c0603 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 23 May 2013 14:35:19 -0700 Subject: [PATCH 249/303] fix suffix for extratemplate for kvm --- .../cloud/server/ManagementServerImpl.java | 42 ++----------------- .../cloud/storage/upload/UploadMonitor.java | 3 +- .../storage/upload/UploadMonitorImpl.java | 4 +- 3 files changed, 8 insertions(+), 41 deletions(-) diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index a8185b861ae..17f87a58774 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -3440,33 +3440,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe extractMode = mode.equals(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; } - // If mode is upload perform extra checks on url and also see if there - // is an ongoing upload on the same. - if (extractMode == Upload.Mode.FTP_UPLOAD) { - URI uri = new URI(url); - if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp"))) { - throw new IllegalArgumentException("Unsupported scheme for url: " + url); - } - - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { - throw new IllegalArgumentException("Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new IllegalArgumentException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); - } - } catch (UnknownHostException uhe) { - throw new IllegalArgumentException("Unable to resolve " + host); - } - - if (_uploadMonitor.isTypeUploadInProgress(volumeId, Upload.Type.VOLUME)) { - throw new IllegalArgumentException(volume.getName() - + " upload is in progress. Please wait for some time to schedule another upload for the same"); - } - } - long accountId = volume.getAccountId(); StoragePool srcPool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); DataStore secStore = this.dataStoreMgr.getImageStore(zoneId); @@ -3526,7 +3499,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe throw new CloudRuntimeException(errorString); } - String volumeLocalPath = "volumes/" + volume.getId() + "/" + cvAnswer.getVolumePath() + "." + getFormatForPool(srcPool); + String volumeLocalPath = "volumes/" + volume.getId() + "/" + cvAnswer.getVolumePath() + "." + volume.getFormat().toString().toLowerCase(); //Fang: volss, handle the ova special case; if (getFormatForPool(srcPool) == "ova") { CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, cvAnswer.getVolumePath(), srcPool, copyvolumewait); @@ -3546,16 +3519,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe uploadJob.setInstallPath(volumeLocalPath); _uploadDao.update(uploadJob.getId(), uploadJob); - if (extractMode == Mode.FTP_UPLOAD) { // Now that the volume is - // copied perform the actual - // uploading - _uploadMonitor.extractVolume(uploadJob, secStore, volume, url, zoneId, volumeLocalPath, cmd.getStartEventId(), job.getId(), _asyncMgr); - return uploadJob.getId(); - } else { // Volume is copied now make it visible under apache and - // create a URL. - _uploadMonitor.createVolumeDownloadURL(volumeId, volumeLocalPath, Upload.Type.VOLUME, zoneId, uploadJob.getId()); - return uploadJob.getId(); - } + // create a URL. + _uploadMonitor.createVolumeDownloadURL(volumeId, volumeLocalPath, Upload.Type.VOLUME, zoneId, uploadJob.getId(), volume.getFormat()); + return uploadJob.getId(); } } diff --git a/server/src/com/cloud/storage/upload/UploadMonitor.java b/server/src/com/cloud/storage/upload/UploadMonitor.java index 4e410480312..b4ba5319481 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitor.java +++ b/server/src/com/cloud/storage/upload/UploadMonitor.java @@ -22,6 +22,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import com.cloud.async.AsyncJobManager; import com.cloud.host.HostVO; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Upload.Mode; import com.cloud.storage.Upload.Status; import com.cloud.storage.Upload.Type; @@ -57,6 +58,6 @@ public interface UploadMonitor extends Manager{ TemplateDataStoreVO vmTemplateStore, Long dataCenterId, long eventId); void createVolumeDownloadURL(Long entityId, String path, Type type, - Long dataCenterId, Long uploadId); + Long dataCenterId, Long uploadId, ImageFormat format); } \ No newline at end of file diff --git a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java index 202536176a4..7d75599faad 100755 --- a/server/src/com/cloud/storage/upload/UploadMonitorImpl.java +++ b/server/src/com/cloud/storage/upload/UploadMonitorImpl.java @@ -260,7 +260,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { } @Override - public void createVolumeDownloadURL(Long entityId, String path, Type type, Long dataCenterId, Long uploadId) { + public void createVolumeDownloadURL(Long entityId, String path, Type type, Long dataCenterId, Long uploadId, ImageFormat format) { String errorString = ""; boolean success = false; @@ -278,7 +278,7 @@ public class UploadMonitorImpl extends ManagerBase implements UploadMonitor { _uploadDao.update(uploadJob.getId(), uploadJob); // Create Symlink at ssvm - String uuid = UUID.randomUUID().toString() + path.substring(path.length() - 4) ; // last 4 characters of the path specify the format like .vhd + String uuid = UUID.randomUUID().toString() + "." + format.toString().toLowerCase() ; DataStore secStore = this.storeMgr.getDataStore(ApiDBUtils.findUploadById(uploadId).getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(secStore); if( ep == null ) { From c163846044bebebecf6e01d99ba95323f7d98c4a Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 23 May 2013 16:49:16 -0700 Subject: [PATCH 250/303] CLOUDSTACK-2538: object_store - UI - zone wizard - add secondary storage step - add name field. --- ui/scripts/zoneWizard.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/ui/scripts/zoneWizard.js b/ui/scripts/zoneWizard.js index 19e728db8f9..85a89cb6951 100755 --- a/ui/scripts/zoneWizard.js +++ b/ui/scripts/zoneWizard.js @@ -1520,7 +1520,8 @@ } }, secondaryStorage: { - fields: { + fields: { + name: { label: 'label.name' }, provider: { label: 'Provider', select: function(args){ @@ -1565,6 +1566,7 @@ $fields.filter('[rel=sockettimeout]').hide(); $fields.filter('[rel=createNfsCache]').hide(); + $fields.filter('[rel=createNfsCache]').find('input').removeAttr('checked'); $fields.filter('[rel=nfsCacheNfsServer]').hide(); $fields.filter('[rel=nfsCachePath]').hide(); @@ -1618,6 +1620,7 @@ $fields.filter('[rel=sockettimeout]').hide(); $fields.filter('[rel=createNfsCache]').hide(); + $fields.filter('[rel=createNfsCache]').find('input').removeAttr('checked'); $fields.filter('[rel=nfsCacheNfsServer]').hide(); $fields.filter('[rel=nfsCachePath]').hide(); @@ -3664,16 +3667,23 @@ addSecondaryStorage: function(args) { message(dictionary['message.creating.secondary.storage']); + var data = {}; + if(args.data.secondaryStorage.name != null && args.data.secondaryStorage.name.length > 0) { + $.extend(data, { + name: args.data.secondaryStorage.name + }); + } + if(args.data.secondaryStorage.provider == 'NFS') { var nfs_server = args.data.secondaryStorage.nfsServer; var path = args.data.secondaryStorage.path; var url = nfsURL(nfs_server, path); - var data = { + $.extend(data, { provider: 'NFS', zoneid: args.data.returnedZone.id, url: url - }; + }); $.ajax({ url: createURL('addImageStore'), @@ -3692,7 +3702,7 @@ }); } else if(args.data.secondaryStorage.provider == 'S3') { - var data = { + $.extend(data, { provider: args.data.secondaryStorage.provider, 'details[0].key': 'accesskey', 'details[0].value': args.data.secondaryStorage.accesskey, @@ -3702,7 +3712,8 @@ 'details[2].value': args.data.secondaryStorage.bucket, 'details[3].key': 'usehttps', 'details[3].value': (args.data.secondaryStorage.usehttps != null && args.data.secondaryStorage.usehttps == 'on' ? 'true' : 'false') - }; + }); + var index = 4; if(args.data.secondaryStorage.endpoint != null && args.data.secondaryStorage.endpoint.length > 0){ data['details[' + index.toString() + '].key'] = 'endpoint'; @@ -3766,10 +3777,11 @@ } } else if(args.data.secondaryStorage.provider == 'Swift') { - var data = { + $.extend(data, { provider: args.data.secondaryStorage.provider, url: args.data.secondaryStorage.url - }; + }); + var index = 0; if(args.data.secondaryStorage.account != null && args.data.secondaryStorage.account.length > 0){ data['details[' + index.toString() + '].key'] = 'account'; From 57049d5aef56f0f5f7b75e0c289fa8618275d745 Mon Sep 17 00:00:00 2001 From: Jessica Wang Date: Thu, 23 May 2013 17:08:37 -0700 Subject: [PATCH 251/303] CLOUDSTACK-2538: object_store - UI - Infrastrcuture menu - secondary storages page - add secondary storage step - add name field. --- ui/scripts/system.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index ea443717fec..76f797cd220 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -10929,7 +10929,8 @@ createForm: { title: 'label.add.secondary.storage', - fields: { + fields: { + name: { label: 'label.name' }, provider: { label: 'Provider', select: function(args){ @@ -10970,6 +10971,8 @@ $form.find('.form-item[rel=connectiontimeout]').hide(); $form.find('.form-item[rel=maxerrorretry]').hide(); $form.find('.form-item[rel=sockettimeout]').hide(); + + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); $form.find('.form-item[rel=createNfsCache]').hide(); $form.find('.form-item[rel=nfsCacheZoneid]').hide(); $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); @@ -11025,6 +11028,8 @@ $form.find('.form-item[rel=connectiontimeout]').hide(); $form.find('.form-item[rel=maxerrorretry]').hide(); $form.find('.form-item[rel=sockettimeout]').hide(); + + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); $form.find('.form-item[rel=createNfsCache]').hide(); $form.find('.form-item[rel=nfsCacheZoneid]').hide(); $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); @@ -11163,17 +11168,24 @@ }, action: function(args) { + var data = {}; + if(args.data.name != null && args.data.name.length > 0) { + $.extend(data, { + name: args.data.name + }); + } + if(args.data.provider == 'NFS') { var zoneid = args.data.zoneid; var nfs_server = args.data.nfsServer; var path = args.data.path; var url = nfsURL(nfs_server, path); - var data = { + $.extend(data, { provider: args.data.provider, zoneid: zoneid, url: url - }; + }); $.ajax({ url: createURL('addImageStore'), @@ -11191,7 +11203,7 @@ }); } else if(args.data.provider == 'S3') { - var data = { + $.extend(data, { provider: args.data.provider, 'details[0].key': 'accesskey', 'details[0].value': args.data.accesskey, @@ -11201,7 +11213,8 @@ 'details[2].value': args.data.bucket, 'details[3].key': 'usehttps', 'details[3].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false') - }; + }); + var index = 4; if(args.data.endpoint != null && args.data.endpoint.length > 0){ data['details[' + index.toString() + '].key'] = 'endpoint'; @@ -11264,10 +11277,11 @@ } } else if(args.data.provider == 'Swift') { - var data = { + $.extend(data, { provider: args.data.provider, url: args.data.url - }; + }); + var index = 0; if(args.data.account != null && args.data.account.length > 0){ data['details[' + index.toString() + '].key'] = 'account'; From d1704a389aaf4e0f2a09301bc105546b4935802c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 16:43:14 -0700 Subject: [PATCH 252/303] Exclude removed template from template sync. --- .../com/cloud/storage/dao/VMTemplateDao.java | 1 + .../cloud/storage/dao/VMTemplateDaoImpl.java | 29 ++++++--- .../storage/image/TemplateServiceImpl.java | 30 ++++++++- .../driver/S3ImageStoreDriverImpl.java | 59 ++++++++---------- .../driver/SwiftImageStoreDriverImpl.java | 61 ++++++++----------- .../cloud/template/TemplateManagerImpl.java | 2 +- 6 files changed, 99 insertions(+), 83 deletions(-) diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java index 74822bcb2a9..b4376fd550e 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java @@ -50,6 +50,7 @@ public interface VMTemplateDao extends GenericDao, StateDao< public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); public List listAllInZone(long dataCenterId); + public List listAllActive(); public List listByHypervisorType(List hyperTypes); public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index a8c2455e6ab..7bd8b6d88dc 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -110,6 +110,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem protected SearchBuilder AccountIdSearch; protected SearchBuilder NameSearch; protected SearchBuilder TmpltsInZoneSearch; + protected SearchBuilder ActiveTmpltSearch; private SearchBuilder PublicSearch; private SearchBuilder NameAccountIdSearch; private SearchBuilder PublicIsoSearch; @@ -368,6 +369,10 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem tmpltZoneSearch.done(); TmpltsInZoneSearch.done(); + ActiveTmpltSearch = createSearchBuilder(); + ActiveTmpltSearch.and("removed", ActiveTmpltSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + + CountTemplatesByAccount = createSearchBuilder(Long.class); CountTemplatesByAccount.select(null, Func.COUNT, null); CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); @@ -556,12 +561,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - + if (zoneType != null) { dataCenterJoin = " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)"; dataCenterJoin += " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - + if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ){ lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } @@ -749,7 +754,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return templateZonePairList; } */ - + /* private String getExtrasWhere(TemplateFilter templateFilter, String name, String keyword, boolean isIso, Boolean bootable, HypervisorType hyperType, Long zoneId, boolean onlyReady, boolean showDomr, String zoneType) { String sql = ""; @@ -781,15 +786,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sql += " AND h.data_center_id = " +zoneId; } }else if (zoneId != null){ - sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; + sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; }else{ sql += " AND tzr.removed is null "; } - - if (zoneType != null){ + + if (zoneType != null){ sql += " AND dc.networktype = '" + zoneType + "'"; - } - + } + if (!showDomr){ sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'"; } @@ -854,7 +859,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return listBy(sc); } + + @Override + public List listAllActive() { + SearchCriteria sc = ActiveTmpltSearch.create(); + return listBy(sc); + } + + @Override public List listDefaultBuiltinTemplates() { SearchCriteria sc = tmpltTypeSearch.create(); sc.setParameters("templateType", Storage.TemplateType.BUILTIN); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 597bbbe060d..eb6e44c9c46 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -40,11 +40,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; @@ -57,6 +59,7 @@ import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.image.store.TemplateObject; import com.cloud.agent.api.Answer; @@ -64,9 +67,12 @@ import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; +import com.cloud.api.query.dao.UserVmJoinDao; +import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; @@ -84,6 +90,7 @@ import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; +import com.cloud.utils.fsm.NoTransitionException; import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @@ -121,12 +128,17 @@ public class TemplateServiceImpl implements TemplateService { @Inject UserVmDao _userVmDao; @Inject + UserVmJoinDao _userVmJoinDao; + @Inject VolumeDao _volumeDao; @Inject TemplateDataFactory _templateFactory; @Inject VMTemplatePoolDao _tmpltPoolDao; @Inject EndPointSelector _epSelector; + @Inject + ImageDataManager imageMgr; + class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; @@ -264,7 +276,7 @@ public class TemplateServiceImpl implements TemplateService { List allTemplates = null; if (zoneId == null){ // region wide store - allTemplates = _templateDao.listAll(); + allTemplates = _templateDao.listAllActive(); } else{ // zone wide store @@ -326,7 +338,7 @@ public class TemplateServiceImpl implements TemplateService { tmlpt.setSize(tmpltInfo.getSize()); _templateDao.update(tmplt.getId(), tmlpt); - if (tmpltInfo.getSize() > 0) { + if (tmpltInfo.getSize() > 0 && tmplt.getUrl() != null) { long accountId = tmplt.getAccountId(); try { _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(accountId), @@ -418,7 +430,7 @@ public class TemplateServiceImpl implements TemplateService { for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); - List userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId()); + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(tInfo.getId()); //check if there is any Vm using this ISO. if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { //TODO: we cannot directly call deleteTemplateSync here to reuse delete logic since in this case, our db does not have this template at all. @@ -610,6 +622,18 @@ public class TemplateServiceImpl implements TemplateService { long storeId = store.getId(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); for ( VMTemplateVO tmplt : rtngTmplts ) { + // set template ready state + if ( tmplt.getState() != TemplateState.Ready ){ + try { + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, + _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, + _templateDao); + } catch (NoTransitionException e) { + // non fatal though + s_logger.debug("failed to update system vm template state to Ready", e); + } + } TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); if ( tmpltStore == null ) { tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, tmplt.getUrl()); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 1c6e17e8e1b..3fd5930a86e 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -291,46 +291,35 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); - // check if there is any VM using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - result.setSuccess(false); - result.setResult("Delete template failed"); - callback.complete(result); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSuccess(false); + result.setResult("Delete template failed"); + callback.complete(result); - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - result.setSuccess(true); - callback.complete(result); - } + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSuccess(true); + callback.complete(result); + } - // for S3, a template can be associated with multiple zones - List templateZones = templateZoneDao - .listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } + // for S3, a template can be associated with multiple zones + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); } } - } else{ - // cannot delete iso due to some VMs are using this - s_logger.debug("Cannot delete iso since some user vms are referencing it"); - CommandResult result = new CommandResult(); - result.setResult("Cannot delete iso since some user vms are referencing it"); - callback.complete(result); } } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 590b653bdff..b8f666e4725 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -285,48 +285,37 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); - // check if there is any VM using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - //result.setSucess(false); - result.setResult("Delete template failed"); - callback.complete(result); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + // result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - //result.setSucess(true); - callback.complete(result); - } + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + // result.setSucess(true); + callback.complete(result); + } - // for Swift, a template can be associated with multiple zones - List templateZones = templateZoneDao - .listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } + // for Swift, a template can be associated with multiple zones + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); } } - } else{ - // cannot delete iso due to some VMs are using this - s_logger.debug("Cannot delete iso since some user vms are referencing it"); - CommandResult result = new CommandResult(); - result.setResult("Cannot delete iso since some user vms are referencing it"); - callback.complete(result); } - } + } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { SnapshotObject snapshotObj = (SnapshotObject)data; diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c5e80b01ffe..3e3616fa96b 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1155,7 +1155,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. - if (!userVmUsingIso.isEmpty()) { + if (userVmUsingIso != null && !userVmUsingIso.isEmpty()) { throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); } From 913e2b38bfe5b29c0c172171e83d4fb7f8a8e6d6 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 23 May 2013 17:22:44 -0700 Subject: [PATCH 253/303] CLOUDSTACK-2523: Recurring snapshot failed with NPE. --- .../com/cloud/storage/snapshot/SnapshotSchedulerImpl.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java index 5af0af00ae4..9b6d2188385 100644 --- a/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotSchedulerImpl.java @@ -56,6 +56,7 @@ import com.cloud.utils.DateUtil; import com.cloud.utils.DateUtil.IntervalType; import com.cloud.utils.NumbersUtil; +import com.cloud.utils.component.ComponentContext; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.concurrency.TestClock; import com.cloud.utils.db.DB; @@ -75,7 +76,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu @Inject protected AsyncJobManager _asyncMgr; @Inject protected VolumeDao _volsDao; @Inject protected ConfigurationDao _configDao; - + private static final int ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION = 5; // 5 seconds private int _snapshotPollInterval; private Timer _testClockTimer; @@ -246,6 +247,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu params.put("ctxStartEventId", String.valueOf(eventId)); CreateSnapshotCmd cmd = new CreateSnapshotCmd(); + ComponentContext.inject(cmd); ApiDispatcher.getInstance().dispatchCreateCmd(cmd, params); params.put("id", ""+cmd.getEntityId()); params.put("ctxStartEventId", "1"); @@ -350,7 +352,7 @@ public class SnapshotSchedulerImpl extends ManagerBase implements SnapshotSchedu _testTimerTask = new TestClock(this, minutesPerHour, hoursPerDay, daysPerWeek, daysPerMonth, weeksPerMonth, monthsPerYear); } _currentTimestamp = new Date(); - + s_logger.info("Snapshot Scheduler is configured."); return true; From 3ec52807f1403129d353e8489636b60beeaf80db Mon Sep 17 00:00:00 2001 From: Edison Su Date: Thu, 23 May 2013 18:25:25 -0700 Subject: [PATCH 254/303] CLOUDSTACK-2593: fix migrate volume between pools through secondary storage --- .../com/cloud/storage/VolumeApiService.java | 2 +- .../command/user/volume/MigrateVolumeCmd.java | 21 ++--- .../src/com/cloud/storage/VolumeVO.java | 2 +- .../StorageCacheRandomAllocator.java | 10 ++- .../motion/AncientDataMotionStrategy.java | 85 ++++++++++++++++--- .../storage/volume/VolumeObject.java | 3 + .../storage/volume/VolumeServiceImpl.java | 2 +- .../resource/XenServerStorageProcessor.java | 3 +- .../com/cloud/storage/VolumeManagerImpl.java | 6 +- 9 files changed, 98 insertions(+), 36 deletions(-) diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index aa52cf74652..31b5c9501b8 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -58,7 +58,7 @@ public interface VolumeApiService { */ Volume resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException; - Volume migrateVolume(MigrateVolumeCmd cmd) throws ConcurrentOperationException; + Volume migrateVolume(MigrateVolumeCmd cmd); /** * Uploads the volume to secondary storage diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java index ce40f0d2979..40e6123d0ec 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/MigrateVolumeCmd.java @@ -98,18 +98,15 @@ public class MigrateVolumeCmd extends BaseAsyncCmd { @Override public void execute(){ - Volume result; - try { - result = _volumeService.migrateVolume(this); - if (result != null) { - VolumeResponse response = _responseGenerator.createVolumeResponse(result); - response.setResponseName(getCommandName()); - this.setResponseObject(response); - } - } catch (ConcurrentOperationException e) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate volume: "); - } - + Volume result; + result = _volumeService.migrateVolume(this); + if (result != null) { + VolumeResponse response = _responseGenerator.createVolumeResponse(result); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to migrate volume"); + } } } diff --git a/engine/schema/src/com/cloud/storage/VolumeVO.java b/engine/schema/src/com/cloud/storage/VolumeVO.java index a230991f42a..d939910a780 100755 --- a/engine/schema/src/com/cloud/storage/VolumeVO.java +++ b/engine/schema/src/com/cloud/storage/VolumeVO.java @@ -154,7 +154,7 @@ public class VolumeVO implements Volume { this.uuid = UUID.randomUUID().toString(); } - public VolumeVO(String name, long dcId, long podId, long accountId, long domainId, Long instanceId, String folder, String path, long size, Volume.Type vType) { + public VolumeVO(String name, Long dcId, Long podId, long accountId, long domainId, Long instanceId, String folder, String path, long size, Volume.Type vType) { this.name = name; this.accountId = accountId; this.domainId = domainId; 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 index 462f13fca77..f8232b8987a 100644 --- 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 @@ -25,26 +25,30 @@ 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 org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.storage.ScopeType; -import com.cloud.utils.exception.CloudRuntimeException; import edu.emory.mathcs.backport.java.util.Collections; @Component public class StorageCacheRandomAllocator implements StorageCacheAllocator { + private static final Logger s_logger = Logger + .getLogger(StorageCacheRandomAllocator.class); @Inject DataStoreManager dataStoreMgr; @Override public DataStore getCacheStore(Scope scope) { if (scope.getScopeType() != ScopeType.ZONE) { - throw new CloudRuntimeException("Can only support zone wide cache storage"); + s_logger.debug("Can only support zone wide cache storage"); + return null; } List cacheStores = dataStoreMgr.getImageCacheStores(scope); if (cacheStores.size() <= 0) { - throw new CloudRuntimeException("Can't find cache storage in zone: " + scope.getScopeId()); + s_logger.debug("Can't find cache storage in zone: " + scope.getScopeId()); + return null; } Collections.shuffle(cacheStores); 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 index 1e99e9efbe2..65beb40c475 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -31,6 +31,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; @@ -39,11 +40,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataObjectType; @@ -57,6 +60,7 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ImageStore; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeManager; @@ -136,6 +140,20 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } return true; } + + private Scope getZoneScope(Scope destScope) { + ZoneScope zoneScope = null; + if (destScope instanceof ClusterScope) { + ClusterScope clusterScope = (ClusterScope) destScope; + zoneScope = new ZoneScope(clusterScope.getZoneId()); + } else if (destScope instanceof HostScope) { + HostScope hostScope = (HostScope) destScope; + zoneScope = new ZoneScope(hostScope.getZoneId()); + } else { + zoneScope = (ZoneScope)destScope; + } + return zoneScope; + } protected Answer copyObject(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); @@ -145,14 +163,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { try { if (needCacheStorage(srcData, destData)) { // need to copy it to image cache store - Scope destScope = destData.getDataStore().getScope(); - if (destScope instanceof ClusterScope) { - ClusterScope clusterScope = (ClusterScope) destScope; - destScope = new ZoneScope(clusterScope.getZoneId()); - } else if (destScope instanceof HostScope) { - HostScope hostScope = (HostScope) destScope; - destScope = new ZoneScope(hostScope.getZoneId()); - } + Scope destScope = getZoneScope(destData.getDataStore().getScope()); cacheData = cacheMgr.createCacheObject(srcData, destScope); CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _primaryStorageDownloadWait); EndPoint ep = selector.select(cacheData, destData); @@ -248,11 +259,57 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - DataObject cacheData = cacheMgr.createCacheObject(srcData, destData.getDataStore().getScope()); - CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); - EndPoint ep = selector.select(cacheData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; + Scope destScope = getZoneScope(destData.getDataStore().getScope()); + DataStore cacheStore = cacheMgr.getCacheStorage(destScope); + if (cacheStore == null) { + //need to find a nfs image store, assuming that can't copy volume directly to s3 + ImageStoreEntity imageStore = (ImageStoreEntity)this.dataStoreMgr.getImageStore(destScope.getScopeId()); + if (!imageStore.getProtocol().equalsIgnoreCase("nfs")) { + s_logger.debug("can't find a nfs image store"); + return null; + } + + DataObject objOnImageStore = imageStore.create(srcData); + objOnImageStore.processEvent(Event.CreateOnlyRequested); + + Answer answer = this.copyObject(srcData, objOnImageStore); + if (answer == null || !answer.getResult()) { + if (answer != null) { + s_logger.debug("copy to image store failed: " + answer.getDetails()); + } + objOnImageStore.processEvent(Event.OperationFailed); + imageStore.delete(objOnImageStore); + return answer; + } + + objOnImageStore.processEvent(Event.OperationSuccessed, answer); + + objOnImageStore.processEvent(Event.CopyingRequested); + + CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(objOnImageStore, destData); + answer = ep.sendMessage(cmd); + + if (answer == null || !answer.getResult()) { + if (answer != null) { + s_logger.debug("copy to primary store failed: " + answer.getDetails()); + } + objOnImageStore.processEvent(Event.OperationFailed); + imageStore.delete(objOnImageStore); + return answer; + } + + objOnImageStore.processEvent(Event.OperationSuccessed); + imageStore.delete(objOnImageStore); + return answer; + } else { + DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(cacheData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; + } + } @Override @@ -273,7 +330,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { answer = cloneVolume(srcData, destData); } else if (destData.getType() == DataObjectType.VOLUME && srcData.getType() == DataObjectType.VOLUME && srcData.getDataStore().getRole() == DataStoreRole.Primary && destData.getDataStore().getRole() == DataStoreRole.Primary) { - answer = copyVolumeBetweenPools(srcData, destData); + answer = copyVolumeBetweenPools(srcData, destData); } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) { answer = copySnapshot(srcData, destData); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index da5e80ba6c0..c5ba6dbe777 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -193,6 +193,9 @@ public class VolumeObject implements VolumeInfo { } if (this.dataStore.getRole() == DataStoreRole.Image) { objectInStoreMgr.update(this, event); + if (this.volumeVO.getState() == Volume.State.Migrating) { + return; + } if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { volEvent = Volume.Event.UploadRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index ba4693cbfbe..a8d7103d0b9 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -615,7 +615,7 @@ public class VolumeServiceImpl implements VolumeService { .setContext(context); motionSrv.copyAsync(srcVolume, destVolume, caller); } catch (Exception e) { - s_logger.debug("Failed to copy volume", e); + s_logger.debug("Failed to copy volume" + e); res.setResult(e.toString()); future.complete(res); } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java index 29ffa4e26b7..399e2341b56 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java @@ -957,7 +957,8 @@ public class XenServerStorageProcessor implements StorageProcessor { try { SR primaryStoragePool = hypervisorResource.getStorageRepository(conn, primaryStore.getUuid()); String srUuid = primaryStoragePool.getUuid(conn); - String volumePath = nfsStore.getUrl() + ":" + srcVolume.getPath(); + URI uri = new URI(nfsStore.getUrl()); + String volumePath = uri.getHost() + ":" + uri.getPath() + File.separator + srcVolume.getPath(); String uuid = copy_vhd_from_secondarystorage(conn, volumePath, srUuid, wait ); VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(uuid); diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index e98939dd7ad..17d5ee8bb2b 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -719,7 +719,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { Transaction txn = Transaction.currentTxn(); txn.start(); - VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1, + VolumeVO volume = new VolumeVO(volumeName, zoneId, -1L, -1L, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); Account owner = (caller.getId() == ownerId) ? caller : _accountMgr .getActiveAccountById(ownerId); @@ -965,7 +965,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { Transaction txn = Transaction.currentTxn(); txn.start(); - VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1, + VolumeVO volume = new VolumeVO(userSpecifiedName, -1L, -1L, -1, -1, new Long(-1), null, null, 0, Volume.Type.DATADISK); volume.setPoolId(null); volume.setDataCenterId(zoneId); @@ -2095,7 +2095,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { try { VolumeApiResult result = future.get(); if (result.isFailed()) { - s_logger.debug("migrate volume failed:" + result.getResult()); + s_logger.error("migrate volume failed:" + result.getResult()); return null; } return result.getVolume(); From 3c7fb2f790bcef6f86ccb735e25f9ef27f1e039a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 24 May 2013 09:50:40 -0700 Subject: [PATCH 255/303] Use template_view.state column to indicate readiness of a template. --- .../api/query/dao/TemplateJoinDaoImpl.java | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 5a5ac785a1b..83291f84448 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -25,10 +25,9 @@ import javax.ejb.Local; import javax.inject.Inject; import org.apache.cloudstack.api.BaseCmd; -import org.apache.cloudstack.api.response.ResourceTagResponse; import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.TemplateZoneResponse; -import org.apache.cloudstack.api.response.VolumeResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -36,20 +35,10 @@ import com.cloud.api.ApiDBUtils; import com.cloud.api.ApiResponseHelper; import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.api.query.vo.TemplateJoinVO; -import com.cloud.api.query.vo.VolumeJoinVO; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.DataCenter; -import com.cloud.offering.ServiceOffering; -import com.cloud.server.ResourceTag; -import com.cloud.server.ResourceTag.TaggedResourceType; -import com.cloud.storage.GuestOS; -import com.cloud.storage.Storage; import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.Volume; import com.cloud.template.VirtualMachineTemplate; import com.cloud.user.Account; import com.cloud.user.UserContext; @@ -91,7 +80,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im tmpltZoneSearch = createSearchBuilder(); tmpltZoneSearch.and("id", tmpltZoneSearch.entity().getId(), SearchCriteria.Op.EQ); tmpltZoneSearch.and("dataCenterId", tmpltZoneSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - tmpltZoneSearch.and("downloadState", tmpltZoneSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); + tmpltZoneSearch.and("state", tmpltZoneSearch.entity().getState(), SearchCriteria.Op.EQ); tmpltZoneSearch.done(); activeTmpltSearch = createSearchBuilder(); @@ -114,7 +103,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im templateResponse.setDisplayText(template.getDisplayText()); templateResponse.setPublic(template.isPublicTemplate()); templateResponse.setCreated(template.getCreatedOnStore()); - templateResponse.setReady(template.getDownloadState() == Status.DOWNLOADED); + templateResponse.setReady(template.getState() == TemplateState.Ready); templateResponse.setFeatured(template.isFeatured()); templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); templateResponse.setPasswordEnabled(template.isEnablePassword()); @@ -304,7 +293,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im isoResponse.setPublic(iso.isPublicTemplate()); isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); isoResponse.setCreated(iso.getCreatedOnStore()); - isoResponse.setReady(iso.getDownloadState() == Status.DOWNLOADED); + isoResponse.setReady(iso.getState() == TemplateState.Ready); isoResponse.setBootable(iso.isBootable()); isoResponse.setFeatured(iso.isFeatured()); isoResponse.setCrossZones(iso.isCrossZones()); @@ -392,7 +381,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im sc.setParameters("id", template.getId()); sc.setParameters("dataCenterId", zoneId); if ( readyOnly ){ - sc.setParameters("downloadState", VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + sc.setParameters("state", TemplateState.Ready); } return searchIncludingRemoved(sc, null, null, false); } From c614c6a424f33f582e6ce4a0e7bf4d72f5606bda Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 24 May 2013 11:10:45 -0700 Subject: [PATCH 256/303] CLOUDSTACK-2674: Secondary Storage garbage collector failed with NPE in case of S3 storage provider. --- .../storage/image/TemplateServiceImpl.java | 7 ++-- .../com/cloud/storage/StorageManagerImpl.java | 2 +- .../com/cloud/template/TemplateManager.java | 2 +- .../cloud/template/TemplateManagerImpl.java | 35 ++++--------------- 4 files changed, 13 insertions(+), 33 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index eb6e44c9c46..fd349710193 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -87,6 +87,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.template.TemplateConstants; import com.cloud.storage.template.TemplateProp; +import com.cloud.template.TemplateManager; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; @@ -138,6 +139,8 @@ public class TemplateServiceImpl implements TemplateService { EndPointSelector _epSelector; @Inject ImageDataManager imageMgr; + @Inject + TemplateManager _tmpltMgr; class TemplateOpContext extends AsyncRpcConext { @@ -430,9 +433,7 @@ public class TemplateServiceImpl implements TemplateService { for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(tInfo.getId()); - //check if there is any Vm using this ISO. - if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + if (_tmpltMgr.templateIsDeleteable(tInfo.getId())) { //TODO: we cannot directly call deleteTemplateSync here to reuse delete logic since in this case, our db does not have this template at all. VMTemplateVO template = _templateDao.findById(tInfo.getId()); DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), null, null); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 0313b491261..cbbbe94abe7 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1133,7 +1133,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C s_logger.debug("Secondary storage garbage collector found " + destroyedTemplateStoreVOs.size() + " templates to cleanup on secondary storage host: " + store.getName()); for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) { - if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateStoreVO)) { + if (!_tmpltMgr.templateIsDeleteable(destroyedTemplateStoreVO.getTemplateId())) { if (s_logger.isDebugEnabled()) { s_logger.debug("Not deleting template at: " + destroyedTemplateStoreVO); } diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index 202feefcb3e..af71d30d9e9 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -92,7 +92,7 @@ public interface TemplateManager extends TemplateApiService{ boolean templateIsDeleteable(VMTemplateHostVO templateHostRef); - boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef); + boolean templateIsDeleteable(long templateId); Pair getAbsoluteIsoPath(long templateId, long dataCenterId); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index eaf9d250cee..c828773bff4 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -945,35 +945,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } @Override - public boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef) { - VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateStoreRef.getTemplateId()); - long templateId = template.getId(); - ImageStoreVO imageStore = _imageStoreDao.findById(templateStoreRef.getDataStoreId()); - long zoneId = imageStore.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); - - // Check if there are VMs running in the template host ref's zone that use the template - List nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId); - - if (!nonExpungedVms.isEmpty()) { - s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are non-expunged VMs deployed from this template."); - return false; - } - List userVmUsingIso = _userVmDao.listByIsoId(templateId); - //check if there is any VM using this ISO. + public boolean templateIsDeleteable(long templateId) { + List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); + //check if there is any Vm using this ISO. We only need to check the case where templateId is an ISO since + // VM can be launched from ISO in secondary storage, while template will always be copied to + // primary storage before deploying VM. if (!userVmUsingIso.isEmpty()) { - s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs"); + s_logger.debug("ISO " + templateId + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs"); return false; } - // Check if there are any snapshots for the template in the template host ref's zone - List volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId); - for (VolumeVO volume : volumes) { - List snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1"); - if (!snapshots.isEmpty()) { - s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are 2.1 snapshots using this template."); - return false; - } - } return true; } @@ -1153,9 +1133,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Please specify a valid iso."); } - List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); // check if there is any VM using this ISO. - if (userVmUsingIso != null && !userVmUsingIso.isEmpty()) { + if (!templateIsDeleteable(templateId)) { throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); } From 89f351c2e5365ba7472a714b66e80bd0186a9efa Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 24 May 2013 11:56:36 -0700 Subject: [PATCH 257/303] Clean up template sync code, and update template state in template sync phase instead of doing it in adding image store. --- .../storage/image/TemplateServiceImpl.java | 68 ++++++++++--------- .../com/cloud/storage/StorageManagerImpl.java | 6 +- 2 files changed, 42 insertions(+), 32 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index fd349710193..c4d04fb9910 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -323,7 +323,8 @@ public class TemplateServiceImpl implements TemplateService { tmpltStore.setErrorString(msg); s_logger.info("msg"); if (tmplt.getUrl() == null) { - msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId(); + msg = "Private Template (" + tmplt + ") with install path " + tmpltInfo.getInstallPath() + + "is corrupted, please check in image store: " + tmpltStore.getDataStoreId(); s_logger.warn(msg); } else { toBeDownloaded.add(tmplt); @@ -340,6 +341,16 @@ public class TemplateServiceImpl implements TemplateService { VMTemplateVO tmlpt = _templateDao.findById(tmplt.getId()); tmlpt.setSize(tmpltInfo.getSize()); _templateDao.update(tmplt.getId(), tmlpt); + // set template to ready state + if (tmplt.getState() != TemplateState.Ready) { + try { + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, _templateDao); + } catch (NoTransitionException e) { + // non fatal though + s_logger.debug("failed to update template " + tmplt.getUniqueName() + " state to Ready", e); + } + } if (tmpltInfo.getSize() > 0 && tmplt.getUrl() != null) { long accountId = tmplt.getAccountId(); @@ -349,8 +360,7 @@ public class TemplateServiceImpl implements TemplateService { tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl())); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, - null, e.getMessage(), e.getMessage()); + _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, null, e.getMessage(), e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); @@ -359,7 +369,8 @@ public class TemplateServiceImpl implements TemplateService { } _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore); } else { - tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); + tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, + tmpltInfo.getInstallPath(), tmplt.getUrl()); tmpltStore.setSize(tmpltInfo.getSize()); tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); tmpltStore.setDataStoreRole(store.getRole()); @@ -370,24 +381,27 @@ public class TemplateServiceImpl implements TemplateService { tmlpt.setSize(tmpltInfo.getSize()); _templateDao.update(tmplt.getId(), tmlpt); associateTemplateToZone(tmplt.getId(), zoneId); + + // set template to ready state + if (tmplt.getState() != TemplateState.Ready) { + try { + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, _templateDao); + } catch (NoTransitionException e) { + // non fatal though + s_logger.debug("failed to update template " + tmplt.getUniqueName() + " state to Ready", e); + } + } + } + } else { + if (tmpltStore != null) { + s_logger.info("Template Sync did not find " + uniqueName + " on image store " + storeId + + ", may request download based on available hypervisor types"); + s_logger.info("Removing leftover template " + uniqueName + " entry from template store table"); + // remove those leftover entries + _vmTemplateStoreDao.remove(tmpltStore.getId()); } - - continue; } - if (tmpltStore != null && tmpltStore.getDownloadState() != Status.DOWNLOADED) { - s_logger.info("Template Sync did not find " + uniqueName + " ready on image store " + storeId + ", will request download to start/resume shortly"); - s_logger.info("Removing template " + uniqueName + " from template store table"); - // remove those leftover entries - _vmTemplateStoreDao.remove(tmpltStore.getId()); - - } else if (tmpltStore == null) { - s_logger.info("Template Sync did not find " + uniqueName + " on the image store " + storeId + ", will request download shortly"); - // persist template_zone_ref table - // TODO: we may have some bugs in removing these entries in case of failure, maybe we should pass another callback below in invoking createTemplateAsync - // to just clear those entries. - associateTemplateToZone(tmplt.getId(), zoneId); - } - } if (toBeDownloaded.size() > 0) { @@ -409,22 +423,14 @@ public class TemplateServiceImpl implements TemplateService { // initiate the download continue; } - // check if there is a record for this template in this store - TemplateDataStoreVO tmpltStoreVO = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); - // if this is private template, and there is no record for this - // template in this store, skip - // TODO: don't understand this logic. What happens if we have a record for this template, still download? + // if this is private template, skip if (!tmplt.isPublicTemplate() && !tmplt.isFeatured()) { - if (tmpltStoreVO == null) { - continue; - } + continue; } if (availHypers.contains(tmplt.getHypervisorType())) { - if (tmpltStoreVO != null && tmpltStoreVO.getDownloadState() == Status.DOWNLOADED) { - continue; - } s_logger.info("Downloading template " + tmplt.getUniqueName() + " to image store " + store.getName()); + associateTemplateToZone(tmplt.getId(), zoneId); TemplateInfo tmpl = _templateFactory.getTemplate(tmplt.getId(), DataStoreRole.Image); createTemplateAsync(tmpl, store, null); } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index cbbbe94abe7..1ac86c856f8 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1751,10 +1751,14 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (((ImageStoreProvider) storeProvider).needDownloadSysTemplate()) { // trigger system vm template download this._imageSrv.downloadBootstrapSysTemplate(store); - } else { + } + // for NFS, template store association will be populated in template sync phase + /* + else { // populate template_store_ref table this._imageSrv.addSystemVMTemplatesToSecondary(store); } + */ // associate builtin template with zones associated with this image // store From 863b534066e43d30fc3f9febd425405a6574605e Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 24 May 2013 13:56:08 -0700 Subject: [PATCH 258/303] Copy iso from S3 to Cache in attach iso to VM. --- .../cloud/template/TemplateManagerImpl.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index c828773bff4..495e8e5d516 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -55,6 +55,8 @@ 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.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.engine.subsystem.api.storage.Scope; +import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; @@ -67,9 +69,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.command.AttachCommand; import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DettachCommand; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; -import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -81,13 +83,13 @@ import org.springframework.stereotype.Component; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.AttachIsoCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; import com.cloud.api.ApiDBUtils; import com.cloud.api.query.dao.UserVmJoinDao; @@ -272,6 +274,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject protected List _adapters; + @Inject + StorageCacheManager cacheMgr; + @Inject + EndPointSelector selector; + + private TemplateAdapter getAdapter(HypervisorType type) { TemplateAdapter adapter = null; if (type == HypervisorType.BareMetal) { @@ -1050,12 +1058,27 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } else if (vm.getState() != State.Running) { return true; } - //FIXME: if it's s3, need to download into cache store TemplateInfo tmplt = this._tmplFactory.getTemplate(isoId, DataStoreRole.Image, vm.getDataCenterId()); if (tmplt == null) { s_logger.warn("ISO: " + isoId + " does not exist"); return false; } + if (tmplt.getDataStore() != null && !(tmplt.getDataStore().getTO() instanceof NfsTO)) { + String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); + int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); + // if it is s3, need to download into cache storage first + Scope destScope = new ZoneScope(vm.getDataCenterId()); + TemplateInfo cacheData = (TemplateInfo) cacheMgr.createCacheObject(tmplt, destScope); + CopyCommand cmd = new CopyCommand(tmplt.getTO(), cacheData.getTO(), _primaryStorageDownloadWait); + EndPoint ep = selector.select(tmplt, cacheData); + Answer answer = ep.sendMessage(cmd); + if (answer != null && answer.getResult()) { + tmplt = cacheData; + } else { + s_logger.error("Failed in copy iso from S3 to cache storage"); + return false; + } + } String vmName = vm.getInstanceName(); From 9e1a9bfd4b33fada025f8776ee29001b034defda Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 24 May 2013 14:24:23 -0700 Subject: [PATCH 259/303] Fix a bug in attachIsoToVM for S3. --- server/src/com/cloud/template/TemplateManagerImpl.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 495e8e5d516..ac66312c6d8 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1064,17 +1064,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return false; } if (tmplt.getDataStore() != null && !(tmplt.getDataStore().getTO() instanceof NfsTO)) { - String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); - int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); // if it is s3, need to download into cache storage first Scope destScope = new ZoneScope(vm.getDataCenterId()); TemplateInfo cacheData = (TemplateInfo) cacheMgr.createCacheObject(tmplt, destScope); - CopyCommand cmd = new CopyCommand(tmplt.getTO(), cacheData.getTO(), _primaryStorageDownloadWait); - EndPoint ep = selector.select(tmplt, cacheData); - Answer answer = ep.sendMessage(cmd); - if (answer != null && answer.getResult()) { - tmplt = cacheData; - } else { + if (cacheData == null){ s_logger.error("Failed in copy iso from S3 to cache storage"); return false; } From c609bc0541c047a509dca0493b8c967b9ff9d3c6 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 24 May 2013 14:34:56 -0700 Subject: [PATCH 260/303] Not reuse already destroyed entries in template_store_ref to make code cleaner. --- .../cloud/template/TemplateManagerImpl.java | 38 +++---------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index ac66312c6d8..ce26837e6a7 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -707,45 +707,19 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // and copy template there, not propagate to all image stores // for that zone for (DataStore dstSecStore : dstSecStores) { - TemplateDataStoreVO dstTmpltStore = null; - try { - dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId, true); - if (dstTmpltStore != null) { - dstTmpltStore = _tmplStoreDao.lockRow(dstTmpltStore.getId(), true); - if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) { - if (dstTmpltStore.getDestroyed() == false) { - return true; // already downloaded on this image - // store - } else { - dstTmpltStore.setDestroyed(false); - _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); - return true; - } - } else if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOAD_ERROR) { - if (dstTmpltStore.getDestroyed() == true) { - dstTmpltStore.setDestroyed(false); - dstTmpltStore.setDownloadState(Status.NOT_DOWNLOADED); - dstTmpltStore.setDownloadPercent(0); - dstTmpltStore.setCopy(true); - dstTmpltStore.setErrorString(""); - dstTmpltStore.setJobId(null); - _tmplStoreDao.update(dstTmpltStore.getId(), dstTmpltStore); - } - } - } - } finally { - txn.commit(); + TemplateDataStoreVO dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId); + if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == Status.DOWNLOADED) { + return true; // already downloaded on this image store } AsyncCallFuture future = this._tmpltSvr.copyTemplate(srcTemplate, dstSecStore); try { TemplateApiResult result = future.get(); if (result.isFailed()) { - s_logger.debug("copy template failed:" + result.getResult()); - return false; + s_logger.debug("copy template failed for image store " + dstSecStore.getName() + ":" + result.getResult()); + continue; // try next image store } - // if(_downloadMonitor.copyTemplate(template, srcSecStore, - // dstSecStore) ) { + _tmpltDao.addTemplateToZone(template, dstZoneId); if (account.getId() != Account.ACCOUNT_ID_SYSTEM) { From 0ed441c6904d5f07a48911ade2fa36ba99afc78c Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 24 May 2013 19:00:10 -0700 Subject: [PATCH 261/303] CLOUDSTACK-2637: fix upload volume --- api/src/com/cloud/storage/Volume.java | 7 +- .../agent/api/ComputeChecksumCommand.java | 16 ++- .../storage/image/store/ImageStoreImpl.java | 20 +++- .../MockLocalNfsSecondaryStorageResource.java | 6 -- .../storage/volume/VolumeObject.java | 13 ++- .../storage/volume/VolumeServiceImpl.java | 99 ++++++++++++++++--- .../cloud/resource/AgentStorageResource.java | 2 +- .../CloudStackImageStoreDriverImpl.java | 5 +- .../com/cloud/storage/VolumeManagerImpl.java | 6 -- .../cloud/template/TemplateManagerImpl.java | 4 +- .../LocalSecondaryStorageResource.java | 6 +- .../resource/NfsSecondaryStorageResource.java | 13 ++- .../resource/SecondaryStorageResource.java | 3 +- .../storage/template/DownloadManagerImpl.java | 6 +- 14 files changed, 138 insertions(+), 68 deletions(-) diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 5d11ba9ed0d..df48de2f321 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -44,6 +44,7 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba Destroying("The volume is destroying, and can't be recovered."), UploadOp ("The volume upload operation is in progress or in short the volume is on secondary storage"), Uploading("volume is uploading"), + Copying("volume is copying from image store to primary, in case it's an uploaded volume"), Uploaded("volume is uploaded"); String _description; @@ -73,9 +74,9 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba s_fsm.addTransition(Resizing, Event.OperationSucceeded, Ready); s_fsm.addTransition(Resizing, Event.OperationFailed, Ready); s_fsm.addTransition(Allocated, Event.UploadRequested, UploadOp); - s_fsm.addTransition(Uploaded, Event.CopyRequested, Creating);// CopyRequested for volume from sec to primary storage - s_fsm.addTransition(Creating, Event.CopySucceeded, Ready); - s_fsm.addTransition(Creating, Event.CopyFailed, Uploaded);// Copying volume from sec to primary failed. + s_fsm.addTransition(Uploaded, Event.CopyRequested, Copying); + s_fsm.addTransition(Copying, Event.OperationSucceeded, Ready); + s_fsm.addTransition(Copying, Event.OperationFailed, Uploaded); s_fsm.addTransition(UploadOp, Event.DestroyRequested, Destroy); s_fsm.addTransition(Ready, Event.DestroyRequested, Destroy); s_fsm.addTransition(Destroy, Event.ExpungingRequested, Expunging); diff --git a/core/src/com/cloud/agent/api/ComputeChecksumCommand.java b/core/src/com/cloud/agent/api/ComputeChecksumCommand.java index a2c88c440a8..95c67bf218c 100755 --- a/core/src/com/cloud/agent/api/ComputeChecksumCommand.java +++ b/core/src/com/cloud/agent/api/ComputeChecksumCommand.java @@ -17,24 +17,32 @@ package com.cloud.agent.api; import com.cloud.agent.api.storage.ssCommand; +import com.cloud.agent.api.to.DataStoreTO; public class ComputeChecksumCommand extends ssCommand { - - + private DataStoreTO store; private String templatePath; public ComputeChecksumCommand() { super(); } - public ComputeChecksumCommand(String secUrl, String templatePath) { - super(secUrl); + public ComputeChecksumCommand(DataStoreTO store, String templatePath) { this.templatePath = templatePath; + this.setStore(store); } public String getTemplatePath() { return templatePath; } + public DataStoreTO getStore() { + return store; + } + + public void setStore(DataStoreTO store) { + this.store = store; + } + } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 1b4dddce2e5..95c952e1cd2 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -20,6 +20,7 @@ package org.apache.cloudstack.storage.image.store; import java.util.Date; import java.util.Set; +import java.util.concurrent.ExecutionException; import javax.inject.Inject; @@ -31,10 +32,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; +import org.apache.log4j.Logger; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.DataStoreRole; @@ -44,6 +48,7 @@ import com.cloud.utils.storage.encoding.EncodingType; public class ImageStoreImpl implements ImageStoreEntity { + private static final Logger s_logger = Logger.getLogger(ImageStoreImpl.class); @Inject VMTemplateDao imageDao; @Inject @@ -145,8 +150,19 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public boolean delete(DataObject obj) { - // TODO Auto-generated method stub - return false; + AsyncCallFuture future = new AsyncCallFuture(); + this.driver.deleteAsync(obj, future); + try { + future.get(); + } catch (InterruptedException e) { + s_logger.debug("failed delete obj", e); + return false; + } catch (ExecutionException e) { + s_logger.debug("failed delete obj", e); + return false; + } + objectInStoreMgr.delete(obj); + return true; } @Override diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index 61c09dbfa30..8e5b1640a06 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -79,12 +79,6 @@ public class MockLocalNfsSecondaryStorageResource extends } - @Override - public String getRootDir(ssCommand cmd) { - return "/mnt"; - - } - @Override public String getRootDir(String secUrl){ return "/mnt"; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index c5ba6dbe777..77a0762f0b9 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -193,15 +193,13 @@ public class VolumeObject implements VolumeInfo { } if (this.dataStore.getRole() == DataStoreRole.Image) { objectInStoreMgr.update(this, event); - if (this.volumeVO.getState() == Volume.State.Migrating) { + if (this.volumeVO.getState() == Volume.State.Migrating || this.volumeVO.getState() == Volume.State.Copying || this.volumeVO.getState() == Volume.State.Uploaded) { return; } - if (event == ObjectInDataStoreStateMachine.Event.CreateRequested) { + if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { volEvent = Volume.Event.UploadRequested; - } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { - volEvent = Volume.Event.CopySucceeded; - } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - volEvent = Volume.Event.CopyFailed; + } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) { + volEvent = Volume.Event.CopyRequested; } } else { if (event == ObjectInDataStoreStateMachine.Event.CreateRequested || @@ -231,7 +229,8 @@ public class VolumeObject implements VolumeInfo { throw new CloudRuntimeException("Failed to update state:" + e.toString()); } finally{ // in case of OperationFailed, expunge the entry - if ( event == ObjectInDataStoreStateMachine.Event.OperationFailed){ + if ( event == ObjectInDataStoreStateMachine.Event.OperationFailed && (this.volumeVO.getState() != Volume.State.Copying + && this.volumeVO.getState() != Volume.State.Uploaded)){ objectInStoreMgr.delete(this); } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index a8d7103d0b9..53a4620c368 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -587,9 +587,71 @@ public class VolumeServiceImpl implements VolumeService { } } + + protected AsyncCallFuture copyVolumeFromImageToPrimary(VolumeInfo srcVolume, DataStore destStore) { + AsyncCallFuture future = new AsyncCallFuture(); + VolumeApiResult res = new VolumeApiResult(srcVolume); + VolumeInfo destVolume = null; + try { + destVolume = (VolumeInfo)destStore.create(srcVolume); + destVolume.processEvent(Event.CopyingRequested); + srcVolume.processEvent(Event.CopyingRequested); + + CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, + destVolume, + destStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyVolumeFromImageToPrimaryCallback(null, null)) + .setContext(context); + + motionSrv.copyAsync(srcVolume, destVolume, caller); + return future; + } catch (Exception e) { + s_logger.error("failed to copy volume from image store", e); + if (destVolume != null) { + destVolume.processEvent(Event.OperationFailed); + } + + srcVolume.processEvent(Event.OperationFailed); + res.setResult(e.toString()); + future.complete(res); + return future; + } + } + + protected Void copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + VolumeInfo srcVolume = context.srcVolume; + VolumeInfo destVolume = context.destVolume; + CopyCommandResult result = callback.getResult(); + AsyncCallFuture future = context.future; + VolumeApiResult res = new VolumeApiResult(destVolume); + try { + if (res.isFailed()) { + destVolume.processEvent(Event.OperationFailed); + srcVolume.processEvent(Event.OperationFailed); + res.setResult(result.getResult()); + future.complete(res); + } + + srcVolume.processEvent(Event.OperationSuccessed); + destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); + srcVolume.getDataStore().delete(srcVolume); + future.complete(res); + } catch (Exception e) { + res.setResult(e.toString()); + future.complete(res); + } + return null; + } + @Override public AsyncCallFuture copyVolume(VolumeInfo srcVolume, DataStore destStore) { + + if (srcVolume.getState() == Volume.State.Uploaded) { + return copyVolumeFromImageToPrimary(srcVolume, destStore); + } + AsyncCallFuture future = new AsyncCallFuture(); VolumeApiResult res = new VolumeApiResult(srcVolume); try { @@ -825,8 +887,8 @@ public class VolumeServiceImpl implements VolumeService { CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)) - .setContext(context); + caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)); + caller.setContext(context); store.getDriver().createAsync(volumeOnStore, caller); return future; @@ -834,19 +896,25 @@ public class VolumeServiceImpl implements VolumeService { protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); + try { + VolumeObject vo = (VolumeObject)context.volume; + if (result.isFailed()) { + vo.processEvent(Event.OperationFailed); + } else { + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); + } - VolumeObject vo = (VolumeObject)context.volume; - if (result.isFailed()) { - vo.processEvent(Event.OperationFailed); - } else { - vo.processEvent(Event.OperationSuccessed, result.getAnswer()); + _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, + vo.getSize()); + VolumeApiResult res = new VolumeApiResult(vo); + context.future.complete(res); + return null; + } catch (Exception e) { + s_logger.error("register volume failed: ", e); + VolumeApiResult res = new VolumeApiResult(null); + context.future.complete(res); + return null; } - - _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, - vo.getSize()); - VolumeApiResult res = new VolumeApiResult(vo); - context.future.complete(res); - return null; } @@ -961,7 +1029,7 @@ public class VolumeServiceImpl implements VolumeService { String url = _volumeStoreDao.findByVolume(volume.getId()).getDownloadUrl(); _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), com.cloud.configuration.Resource.ResourceType.secondary_storage, - volInfo.getSize() - UriUtils.getRemoteSize(url)); + volInfo.getSize() - volInfo.getPhysicalSize()); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), @@ -995,13 +1063,14 @@ public class VolumeServiceImpl implements VolumeService { } //Delete volumes which are not present on DB. + /* for (Long uniqueName : volumeInfos.keySet()) { TemplateProp vInfo = volumeInfos.get(uniqueName); expungeVolumeAsync(volFactory.getVolume(vInfo.getId(), store)); String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId; s_logger.info(description); - } + }*/ } diff --git a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java index a012340d088..3e479aef49a 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java +++ b/plugins/hypervisors/simulator/src/com/cloud/resource/AgentStorageResource.java @@ -109,7 +109,7 @@ public class AgentStorageResource extends AgentResourceBase implements Secondary } @Override - public String getRootDir(ssCommand cmd) { + public String getRootDir(String url) { // TODO Auto-generated method stub return null; } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 71afc13e13c..a6c4696404a 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -212,7 +212,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } - CreateCmdResult result = new CreateCmdResult(null, null); + CreateCmdResult result = new CreateCmdResult(null, answer); caller.complete(result); } return null; @@ -247,8 +247,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { throw new CloudRuntimeException( "Please specify a volume that is not currently being uploaded."); } - _volumeStoreDao.remove(volumeStore.getId()); - volumeDao.remove(vol.getId()); + CommandResult result = new CommandResult(); callback.complete(result); return; diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 17d5ee8bb2b..5b02a9d3841 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -737,12 +737,6 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { .getDomainId()); volume.setFormat(ImageFormat.valueOf(format)); volume = _volsDao.persist(volume); - try { - stateTransitTo(volume, Event.UploadRequested); - } catch (NoTransitionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } UserContext.current().setEventDetails("Volume Id: " + volume.getId()); // Increment resource count during allocation; if actual creation fails, diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index ce26837e6a7..96430afe38b 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -636,11 +636,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override public String getChecksum(DataStore store, String templatePath) { - - String secUrl = store.getUri(); EndPoint ep = _epSelector.select(store); ComputeChecksumCommand cmd = new ComputeChecksumCommand( - secUrl, templatePath); + store.getTO(), templatePath); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { return answer.getDetails(); diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java index d2397427934..5a806bc16c1 100644 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/LocalSecondaryStorageResource.java @@ -21,12 +21,11 @@ import java.util.Map; import javax.naming.ConfigurationException; -import org.apache.log4j.Logger; - import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.cloudstack.storage.template.DownloadManager; import org.apache.cloudstack.storage.template.DownloadManagerImpl; +import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckHealthAnswer; @@ -42,7 +41,6 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupStorageCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; -import com.cloud.agent.api.storage.ssCommand; import com.cloud.agent.api.to.NfsTO; import com.cloud.host.Host; import com.cloud.host.Host.Type; @@ -74,7 +72,7 @@ public class LocalSecondaryStorageResource extends ServerResourceBase implements @Override - public String getRootDir(ssCommand cmd){ + public String getRootDir(String url){ return getRootDir(); } diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index a7c409df634..62b3a62f6c9 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -998,7 +998,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private Answer execute(ComputeChecksumCommand cmd) { String relativeTemplatePath = cmd.getTemplatePath(); - String parent = getRootDir(cmd); + DataStoreTO store = cmd.getStore(); + if (!(store instanceof NfsTO)) { + return new Answer(cmd, false, "can't handle non nfs data store"); + } + NfsTO nfsStore = (NfsTO)store; + String parent = getRootDir(nfsStore.getUrl()); if (relativeTemplatePath.startsWith(File.separator)) { relativeTemplatePath = relativeTemplatePath.substring(1); @@ -1720,12 +1725,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - @Override - public String getRootDir(ssCommand cmd) { - return getRootDir(cmd.getSecUrl()); - - } - protected long getUsedSize(String rootDir) { return _storage.getUsedSpace(rootDir); } diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java index 5c87b0dcc92..ae871a62c29 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/SecondaryStorageResource.java @@ -15,7 +15,6 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.resource; -import com.cloud.agent.api.storage.ssCommand; import com.cloud.resource.ServerResource; /** * @@ -23,6 +22,6 @@ import com.cloud.resource.ServerResource; */ public interface SecondaryStorageResource extends ServerResource { - public String getRootDir(ssCommand cmd); + public String getRootDir(String cmd); } diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index 509364b2759..81ddd673d20 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -692,11 +692,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager String installPathPrefix = cmd.getInstallPath(); // for NFS, we need to get mounted path if (dstore instanceof NfsTO) { - if (ResourceType.TEMPLATE == resourceType) { - installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; - } else { - installPathPrefix = resource.getRootDir(cmd) + File.separator + installPathPrefix; - } + installPathPrefix = resource.getRootDir(((NfsTO) dstore).getUrl()) + File.separator + installPathPrefix; } String user = null; String password = null; From 27133fba7daefcea6ddba943efb9c96f23dacef2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Sat, 25 May 2013 20:48:15 -0700 Subject: [PATCH 262/303] Simplify clean up snapshots logic in secondary storage and consolidate to use one agent command DeleteSnapshotBackupCommand for snapshot deletion task by removing CleanupSnapshotBackupCommand. --- .../api/CleanupSnapshotBackupCommand.java | 75 -------- .../datastore/db/SnapshotDataStoreDao.java | 4 +- .../image/db/SnapshotDataStoreDaoImpl.java | 20 +- .../com/cloud/storage/StorageManagerImpl.java | 67 ++++--- .../resource/NfsSecondaryStorageResource.java | 181 +++++++----------- 5 files changed, 123 insertions(+), 224 deletions(-) delete mode 100644 core/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java diff --git a/core/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java b/core/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java deleted file mode 100644 index ae65a529c52..00000000000 --- a/core/src/com/cloud/agent/api/CleanupSnapshotBackupCommand.java +++ /dev/null @@ -1,75 +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 com.cloud.agent.api; - -import java.util.List; - -public class CleanupSnapshotBackupCommand extends Command { - private String secondaryStoragePoolURL; - private Long dcId; - private Long accountId; - private Long volumeId; - private List validBackupUUIDs; - - protected CleanupSnapshotBackupCommand() { - - } - - /* - * @param secondaryStoragePoolURL This is what shows up in the UI when you click on Secondary storage. - * In the code, it is present as: In the vmops.host_details table, there is a field mount.parent. This is the value of that field - * If you have better ideas on how to get it, you are welcome. - * @param validBackupUUID The VHD which are valid - */ - public CleanupSnapshotBackupCommand(String secondaryStoragePoolURL, - Long dcId, - Long accountId, - Long volumeId, - List validBackupUUIDs) - { - this.secondaryStoragePoolURL = secondaryStoragePoolURL; - this.dcId = dcId; - this.accountId = accountId; - this.volumeId = volumeId; - this.validBackupUUIDs = validBackupUUIDs; - } - - public String getSecondaryStoragePoolURL() { - return secondaryStoragePoolURL; - } - - public Long getDcId() { - return dcId; - } - - public Long getAccountId() { - return accountId; - } - - public Long getVolumeId() { - return volumeId; - } - - public List getValidBackupUUIDs() { - return validBackupUUIDs; - } - - @Override - public boolean executeInSequence() { - return false; - } -} diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index 5f5c586c6a5..f5b46aaa85a 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -35,7 +35,7 @@ public interface SnapshotDataStoreDao extends GenericDao listDestroyed(long storeId); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java index 05a0da081c8..fc3f6bce38d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/SnapshotDataStoreDaoImpl.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; +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 org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; @@ -44,6 +45,7 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase updateStateSearch; private SearchBuilder storeSearch; + private SearchBuilder destroyedSearch; private SearchBuilder snapshotSearch; private SearchBuilder storeSnapshotSearch; @@ -54,9 +56,14 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase listDestroyed(long id) { + SearchCriteria sc = destroyedSearch.create(); + sc.setParameters("store_id", id); + sc.setParameters("store_role", DataStoreRole.Image); + sc.setParameters("state", ObjectInDataStoreStateMachine.State.Destroyed); + return listBy(sc); } } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 1ac86c856f8..3cc9bef7ec3 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -59,6 +59,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; @@ -86,8 +87,8 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.CleanupSnapshotBackupCommand; import com.cloud.agent.api.Command; +import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; @@ -1174,49 +1175,47 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } } - // Cleanup snapshot in secondary storage hosts + // CleanUp snapshots on Secondary Storage. for (DataStore store : imageStores) { try { - List vIDs = findAllVolumeIdInSnapshotTable(store.getId()); - if (vIDs == null) { - continue; - } - for (Long volumeId : vIDs) { - boolean lock = false; - try { - VolumeVO volume = _volsDao.findByIdIncludingRemoved(volumeId); - if (volume.getRemoved() == null) { - volume = _volsDao.acquireInLockTable(volumeId, 10); - if (volume == null) { - continue; - } - lock = true; - } - List snapshots = findAllSnapshotForVolume(volumeId); - if (snapshots == null) { - continue; - } - EndPoint ep = _epSelector.select(store); - CleanupSnapshotBackupCommand cmd = new CleanupSnapshotBackupCommand(store.getUri(), store.getScope().getScopeId(), - volume.getAccountId(), volumeId, snapshots); + List destroyedSnapshotStoreVOs = _snapshotStoreDao.listDestroyed(store.getId()); + s_logger.debug("Secondary storage garbage collector found " + destroyedSnapshotStoreVOs.size() + + " snapshots to cleanup on secondary storage host: " + store.getName()); + for (SnapshotDataStoreVO destroyedSnapshotStoreVO : destroyedSnapshotStoreVOs) { + // check if this snapshot has child + SnapshotInfo snap = snapshotFactory.getSnapshot(destroyedSnapshotStoreVO.getSnapshotId(), store); + if ( snap.getChild() != null ){ + s_logger.debug("Skip snapshot on store: " + destroyedSnapshotStoreVO + " , because it has child"); + continue; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Deleting snapshot on store: " + destroyedSnapshotStoreVO); + } + + String installPath = destroyedSnapshotStoreVO.getInstallPath(); + + if (installPath != null) { + EndPoint ep = _epSelector.select(store); + DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(store.getTO(), store.getUri(), + null, null, null, destroyedSnapshotStoreVO.getInstallPath(), false); Answer answer = ep.sendMessage(cmd); - if ((answer == null) || !answer.getResult()) { - String details = "Failed to cleanup snapshots for volume " + volumeId + " due to " - + (answer == null ? "null" : answer.getDetails()); - s_logger.warn(details); - } - } catch (Exception e1) { - s_logger.warn("problem cleaning up snapshots in secondary storage store " + store.getName(), e1); - } finally { - if (lock) { - _volsDao.releaseFromLockTable(volumeId); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to delete " + destroyedSnapshotStoreVO + " due to " + + ((answer == null) ? "answer is null" : answer.getDetails())); + } else { + _volumeStoreDao.remove(destroyedSnapshotStoreVO.getId()); + s_logger.debug("Deleted snapshot at: " + destroyedSnapshotStoreVO.getInstallPath()); } + } else { + _snapshotStoreDao.remove(destroyedSnapshotStoreVO.getId()); } } + } catch (Exception e2) { s_logger.warn("problem cleaning up snapshots in secondary storage store " + store.getName(), e2); } + } // CleanUp volumes on Secondary Storage. diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 62b3a62f6c9..27a15ccdd83 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -65,7 +65,6 @@ import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; -import com.cloud.agent.api.CleanupSnapshotBackupCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand; @@ -207,7 +206,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } else if (cmd instanceof ListVolumeCommand) { return execute((ListVolumeCommand) cmd); } else if (cmd instanceof DownloadSnapshotFromSwiftCommand) { - return execute((DownloadSnapshotFromSwiftCommand)cmd); + return execute((DownloadSnapshotFromSwiftCommand) cmd); } else if (cmd instanceof DownloadSnapshotFromS3Command) { return execute((DownloadSnapshotFromS3Command) cmd); } else if (cmd instanceof DeleteSnapshotBackupCommand) { @@ -218,8 +217,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((DownloadTemplateFromSwiftToSecondaryStorageCommand) cmd); } else if (cmd instanceof UploadTemplateToSwiftFromSecondaryStorageCommand) { return execute((UploadTemplateToSwiftFromSecondaryStorageCommand) cmd); - } else if (cmd instanceof CleanupSnapshotBackupCommand) { - return execute((CleanupSnapshotBackupCommand) cmd); } else if (cmd instanceof CopyCommand) { return execute((CopyCommand) cmd); } else { @@ -241,8 +238,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S final String errMsg = "Unable to create directory " + downloadPath + " to copy from S3 to cache."; s_logger.error(errMsg); return new CopyCmdAnswer(errMsg); - } - else{ + } else { s_logger.debug("Directory " + downloadPath + " already exists"); } @@ -287,10 +283,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String origPath = destFile.getAbsolutePath(); String extension = null; - if ( srcData.getObjectType() == DataObjectType.TEMPLATE){ - extension = ((TemplateObjectTO)srcData).getFormat().getFileExtension(); - } else{ - extension = ((VolumeObjectTO)srcData).getFormat().getFileExtension(); + if (srcData.getObjectType() == DataObjectType.TEMPLATE) { + extension = ((TemplateObjectTO) srcData).getFormat().getFileExtension(); + } else { + extension = ((VolumeObjectTO) srcData).getFormat().getFileExtension(); } String templateName = UUID.randomUUID().toString(); @@ -301,7 +297,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S scr.add("-t", downloadPath); scr.add("-f", origPath); // this is the temporary - // template file downloaded + // template file downloaded String result; result = scr.execute(); @@ -336,8 +332,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - - protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { + protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, + TemplateObjectTO destData, NfsTO destDataStore) { String srcMountPoint = this.getRootDir(srcDataStore.getUrl()); String snapshotPath = srcData.getPath(); int index = snapshotPath.lastIndexOf("/"); @@ -364,7 +360,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String result = command.execute(); if (result != null && !result.equalsIgnoreCase("")) { - return new CopyCmdAnswer(result); + return new CopyCmdAnswer(result); } Map params = new HashMap(); @@ -372,8 +368,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Processor processor = new VhdProcessor(); processor.configure("Vhd Processor", params); - FormatInfo info = processor.process(destPath, null, - templateUuid); + FormatInfo info = processor.process(destPath, null, templateUuid); TemplateLocation loc = new TemplateLocation(_storage, destPath); loc.create(1, true, templateName); @@ -399,7 +394,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new CopyCmdAnswer(errMsg); } - protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { + protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, + NfsTO destDataStore) { if (srcData.getHypervisorType() == HypervisorType.XenServer) { return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore); @@ -419,8 +415,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return Answer.createUnsupportedCommandAnswer(cmd); } - if (destDataStore instanceof NfsTO){ - return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore); + if (destDataStore instanceof NfsTO) { + return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore, (TemplateObjectTO) destData, + (NfsTO) destDataStore); } } @@ -428,14 +425,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } protected Answer copyFromNfsToImage(CopyCommand cmd) { - DataTO destData = cmd.getDestTO(); - DataStoreTO destDataStore = destData.getDataStore(); + DataTO destData = cmd.getDestTO(); + DataStoreTO destDataStore = destData.getDataStore(); - if (destDataStore instanceof S3TO) { - return copyFromNfsToS3(cmd); - } else { - return new CopyCmdAnswer("unsupported "); - } + if (destDataStore instanceof S3TO) { + return copyFromNfsToS3(cmd); + } else { + return new CopyCmdAnswer("unsupported "); + } } protected Answer execute(CopyCommand cmd) { @@ -448,17 +445,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return createTemplateFromSnapshot(cmd); } - if (srcDataStore instanceof S3TO && destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache){ - S3TO s3 = (S3TO)srcDataStore; - NfsTO destImageStore = (NfsTO)destDataStore; + if (srcDataStore instanceof S3TO && destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) { + S3TO s3 = (S3TO) srcDataStore; + NfsTO destImageStore = (NfsTO) destDataStore; return this.copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore); } if (srcDataStore.getRole() == DataStoreRole.ImageCache && destDataStore.getRole() == DataStoreRole.Image) { - return copyFromNfsToImage(cmd); + return copyFromNfsToImage(cmd); } - return Answer.createUnsupportedCommandAnswer(cmd); } @@ -532,7 +528,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private Answer execute(DownloadCommand cmd) { DataStoreTO dstore = cmd.getDataStore(); - if (dstore instanceof NfsTO || dstore instanceof S3TO ) { + if (dstore instanceof NfsTO || dstore instanceof S3TO) { return _dlMgr.handleDownloadCommand(this, cmd); } /* @@ -625,16 +621,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private ImageFormat getTemplateFormat(String filePath){ + private ImageFormat getTemplateFormat(String filePath) { String ext = null; int extensionPos = filePath.lastIndexOf('.'); int lastSeparator = Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\')); - int i = lastSeparator > extensionPos ? -1 : extensionPos; - if (i > 0 ) { - ext = filePath.substring(i+1); + int i = lastSeparator > extensionPos ? -1 : extensionPos; + if (i > 0) { + ext = filePath.substring(i + 1); } - if ( ext != null){ - if ( ext.equalsIgnoreCase("vhd")) + if (ext != null) { + if (ext.equalsIgnoreCase("vhd")) return ImageFormat.VHD; else if (ext.equalsIgnoreCase("qcow2")) return ImageFormat.QCOW2; @@ -651,21 +647,19 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } protected Answer copyFromNfsToS3(CopyCommand cmd) { - final DataTO srcData = cmd.getSrcTO(); - final DataTO destData = cmd.getDestTO(); - DataStoreTO srcDataStore = srcData.getDataStore(); - NfsTO srcStore = (NfsTO)srcDataStore; - DataStoreTO destDataStore = destData.getDataStore(); + final DataTO srcData = cmd.getSrcTO(); + final DataTO destData = cmd.getDestTO(); + DataStoreTO srcDataStore = srcData.getDataStore(); + NfsTO srcStore = (NfsTO) srcDataStore; + DataStoreTO destDataStore = destData.getDataStore(); - final S3TO s3 = (S3TO)destDataStore; + final S3TO s3 = (S3TO) destDataStore; try { - final String templatePath = determineStorageTemplatePath( - srcStore.getUrl(), srcData.getPath()); + final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath()); if (s_logger.isDebugEnabled()) { - s_logger.debug("Found " + srcData.getObjectType() + " from directory " - + templatePath + " to upload to S3."); + s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3."); } final String bucket = s3.getBucketName(); @@ -676,16 +670,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S DataTO retObj = null; if (destData.getObjectType() == DataObjectType.TEMPLATE) { - TemplateObjectTO newTemplate = new TemplateObjectTO(); - newTemplate.setPath(key); - newTemplate.setSize(srcFile.length()); - newTemplate.setFormat(format); - retObj = newTemplate; + TemplateObjectTO newTemplate = new TemplateObjectTO(); + newTemplate.setPath(key); + newTemplate.setSize(srcFile.length()); + newTemplate.setFormat(format); + retObj = newTemplate; } else if (destData.getObjectType() == DataObjectType.VOLUME) { - VolumeObjectTO newVol = new VolumeObjectTO(); - newVol.setPath(key); - newVol.setSize(srcFile.length()); - retObj = newVol; + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(key); + newVol.setSize(srcFile.length()); + retObj = newVol; } return new CopyCmdAnswer(retObj); @@ -945,8 +939,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId); } - - public Answer execute(DownloadSnapshotFromSwiftCommand cmd){ + public Answer execute(DownloadSnapshotFromSwiftCommand cmd) { SwiftTO swift = cmd.getSwift(); String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); Long accountId = cmd.getAccountId(); @@ -1000,9 +993,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String relativeTemplatePath = cmd.getTemplatePath(); DataStoreTO store = cmd.getStore(); if (!(store instanceof NfsTO)) { - return new Answer(cmd, false, "can't handle non nfs data store"); + return new Answer(cmd, false, "can't handle non nfs data store"); } - NfsTO nfsStore = (NfsTO)store; + NfsTO nfsStore = (NfsTO) store; String parent = getRootDir(nfsStore.getUrl()); if (relativeTemplatePath.startsWith(File.separator)) { @@ -1129,14 +1122,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) { - String lPath = null; - int index = name.lastIndexOf(File.separator); - String snapshotPath = name.substring(0, index); - if (deleteAllFlag) { - lPath = this.getRootDir(secondaryStorageUrl) + File.separator + snapshotPath + File.separator + "*"; - } else { - lPath = this.getRootDir(secondaryStorageUrl) + File.separator + name + "*"; - } + String lPath = null; + int index = name.lastIndexOf(File.separator); + String snapshotPath = name.substring(0, index); + if (deleteAllFlag) { + lPath = this.getRootDir(secondaryStorageUrl) + File.separator + snapshotPath + File.separator + "*"; + } else { + lPath = this.getRootDir(secondaryStorageUrl) + File.separator + name + "*"; + } final String result = deleteLocalFile(lPath); @@ -1328,12 +1321,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } DataStoreTO store = cmd.getDataStore(); if (store instanceof NfsTO) { - NfsTO nfs = (NfsTO)store; + NfsTO nfs = (NfsTO) store; String root = getRootDir(cmd.getSecUrl()); Map templateInfos = _dlMgr.gatherVolumeInfo(root); return new ListVolumeAnswer(cmd.getSecUrl(), templateInfos); - } else if (store instanceof S3TO ){ - S3TO s3 = (S3TO)store; + } else if (store instanceof S3TO) { + S3TO s3 = (S3TO) store; Map templateInfos = s3ListVolume(s3); return new ListVolumeAnswer(s3.getBucketName(), templateInfos); } else { @@ -1512,7 +1505,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S found = true; } - // KVM HA monitor makes a mess in the templates with its heartbeat tests + // KVM HA monitor makes a mess in the templates with its + // heartbeat tests // Don't let this stop us from cleaning up the template if (f.isDirectory() && f.getName().equals("KVMHA")) { s_logger.debug("Deleting KVMHA directory contents from template location"); @@ -1523,8 +1517,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!f.delete()) { - return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " - + relativeTemplatePath); + return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath); } } @@ -1608,7 +1601,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S found = true; } - // KVM HA monitor makes a mess in the templates with its heartbeat tests + // KVM HA monitor makes a mess in the templates with its + // heartbeat tests // Don't let this stop us from cleaning up the template if (f.isDirectory() && f.getName().equals("KVMHA")) { s_logger.debug("Deleting KVMHA directory contents from template location"); @@ -1619,8 +1613,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!f.delete()) { - return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " - + relativeVolumePath); + return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath); } } if (!found) { @@ -1674,35 +1667,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - Answer execute(CleanupSnapshotBackupCommand cmd) { - String parent = getRootDir(cmd.getSecondaryStoragePoolURL()); - if (!parent.endsWith(File.separator)) { - parent += File.separator; - } - String absoluteSnapsthotDir = parent + File.separator + "snapshots" + File.separator + cmd.getAccountId() + File.separator - + cmd.getVolumeId(); - File ssParent = new File(absoluteSnapsthotDir); - if (ssParent.exists() && ssParent.isDirectory()) { - File[] files = ssParent.listFiles(); - for (File file : files) { - boolean found = false; - String filename = file.getName(); - for (String uuid : cmd.getValidBackupUUIDs()) { - if (filename.startsWith(uuid)) { - found = true; - break; - } - } - if (!found) { - file.delete(); - String msg = "snapshot " + filename + " is not recorded in DB, remove it"; - s_logger.warn(msg); - } - } - } - return new Answer(cmd, true, null); - } - synchronized public String getRootDir(String secUrl) { if (!_inSystemVM) { return _parent; @@ -1863,9 +1827,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S _parent = (String) params.get("mount.path"); } - if (_inSystemVM) { - _localgw = (String)params.get("localgw"); + _localgw = (String) params.get("localgw"); if (_localgw != null) { // can only happen inside service vm String mgmtHost = (String) params.get("host"); addRouteToInternalIpOrCidr(_localgw, _eth1ip, _eth1mask, mgmtHost); From 8a1a51c6fc74549f167c65798cad8ad3473a23bf Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 28 May 2013 13:36:54 -0700 Subject: [PATCH 263/303] Clean up deleteSnapshot agent command, since snapshot path is already stored in snapshot_store_ref, no need to construct path in resource side. --- .../api/DeleteSnapshotBackupCommand2.java | 56 +++++++ .../agent/api/DeleteSnapshotsDirCommand.java | 34 ++-- .../CloudStackImageStoreDriverImpl.java | 14 +- .../driver/S3ImageStoreDriverImpl.java | 10 +- .../driver/SwiftImageStoreDriverImpl.java | 11 +- .../com/cloud/storage/StorageManagerImpl.java | 4 +- .../storage/snapshot/SnapshotManager.java | 8 +- .../storage/snapshot/SnapshotManagerImpl.java | 20 +-- .../resource/NfsSecondaryStorageResource.java | 153 ++++++++++++++++-- 9 files changed, 229 insertions(+), 81 deletions(-) create mode 100644 core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java new file mode 100644 index 00000000000..2fcb62a534f --- /dev/null +++ b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java @@ -0,0 +1,56 @@ +// 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.agent.api; + +import com.cloud.agent.api.to.DataStoreTO; + +/** + * This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server + * This currently assumes that the secondary storage are mounted on the XenServer. + */ +public class DeleteSnapshotBackupCommand2 extends Command { + private DataStoreTO store; + private String snapshotPath; + + + public DeleteSnapshotBackupCommand2() { + } + + + public DeleteSnapshotBackupCommand2(DataStoreTO store, + String snapshotPath) + { + this.store = store; + this.snapshotPath = snapshotPath; + } + + + public DataStoreTO getDataStore(){ + return store; + } + + + public String getSnapshotPath() { + return snapshotPath; + } + + + @Override + public boolean executeInSequence() { + return true; + } +} diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java b/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java index e2071d7f746..26d75867851 100644 --- a/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java +++ b/core/src/com/cloud/agent/api/DeleteSnapshotsDirCommand.java @@ -16,27 +16,23 @@ // under the License. package com.cloud.agent.api; +import com.cloud.agent.api.to.DataStoreTO; + /** * This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server * This currently assumes that the secondary storage are mounted on the XenServer. */ public class DeleteSnapshotsDirCommand extends Command { - String secondaryStorageUrl; - Long dcId; - Long accountId; - Long volumeId; + DataStoreTO store; + String directory; protected DeleteSnapshotsDirCommand() { } - public DeleteSnapshotsDirCommand(String secondaryStorageUrl, - Long dcId, Long accountId, Long volumeId) - { - this.secondaryStorageUrl = secondaryStorageUrl; - this.dcId = dcId; - this.accountId = accountId; - this.volumeId = volumeId; + public DeleteSnapshotsDirCommand(DataStoreTO store, String dir) { + this.store = store; + this.directory = dir; } @Override @@ -44,20 +40,12 @@ public class DeleteSnapshotsDirCommand extends Command { return true; } - public String getSecondaryStorageUrl() { - return secondaryStorageUrl; + public DataStoreTO getDataStore() { + return store; } - public Long getDcId() { - return dcId; - } - public Long getAccountId() { - return accountId; + public String getDirectory() { + return directory; } - - public Long getVolumeId() { - return volumeId; - } - } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index a6c4696404a..bc64250d8f8 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -49,6 +49,7 @@ import org.apache.cloudstack.storage.snapshot.SnapshotObject; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; @@ -247,7 +248,7 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { throw new CloudRuntimeException( "Please specify a volume that is not currently being uploaded."); } - + CommandResult result = new CommandResult(); callback.complete(result); return; @@ -326,11 +327,14 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } try { - String secondaryStoragePoolUrl = secStore.getUri(); + String backupOfSnapshot = snapshotObj.getPath(); + if (backupOfSnapshot == null) { + callback.complete(result); + return; + } - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - secStore.getTO(), secondaryStoragePoolUrl, null, null, null, - snapshotObj.getPath(), false); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2( + secStore.getTO(), backupOfSnapshot); EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 3fd5930a86e..1798ded4d05 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -52,6 +52,7 @@ import org.apache.cloudstack.storage.snapshot.SnapshotObject; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; @@ -337,10 +338,6 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } try { - String secondaryStoragePoolUrl = secStore.getUri(); - Long dcId = snapshot.getDataCenterId(); - Long accountId = snapshot.getAccountId(); - Long volumeId = snapshot.getVolumeId(); String backupOfSnapshot = snapshotObj.getPath(); if (backupOfSnapshot == null) { @@ -348,9 +345,8 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { return; } - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId, - backupOfSnapshot, false); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2( + secStore.getTO(), backupOfSnapshot); EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index b8f666e4725..cdfe63e38ac 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -51,6 +51,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; @@ -331,20 +332,14 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } try { - String secondaryStoragePoolUrl = secStore.getUri(); - Long dcId = snapshot.getDataCenterId(); - Long accountId = snapshot.getAccountId(); - Long volumeId = snapshot.getVolumeId(); - String backupOfSnapshot = snapshotObj.getPath(); if (backupOfSnapshot == null) { callback.complete(result); return; } - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand( - secStore.getTO(), secondaryStoragePoolUrl, dcId, accountId, volumeId, - backupOfSnapshot, false); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2( + secStore.getTO(), backupOfSnapshot); EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 3cc9bef7ec3..bb613b642f1 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -89,6 +89,7 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; @@ -1197,8 +1198,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (installPath != null) { EndPoint ep = _epSelector.select(store); - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(store.getTO(), store.getUri(), - null, null, null, destroyedSnapshotStoreVO.getInstallPath(), false); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(store.getTO(), destroyedSnapshotStoreVO.getInstallPath()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + destroyedSnapshotStoreVO + " due to " diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManager.java b/server/src/com/cloud/storage/snapshot/SnapshotManager.java index d6e0af66da2..027fad6dbcb 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManager.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManager.java @@ -34,8 +34,8 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.fsm.NoTransitionException; /** - * - * + * + * */ public interface SnapshotManager { @@ -51,7 +51,7 @@ public interface SnapshotManager { * For each of the volumes in the account, (which can span across multiple zones and multiple secondary storages), delete * the dir on the secondary storage which contains the backed up snapshots for that volume. This is called during * deleteAccount. - * + * * @param accountId * The account which is to be deleted. */ @@ -59,7 +59,7 @@ public interface SnapshotManager { String getSecondaryStorageURL(SnapshotVO snapshot); - void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId); + //void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId); boolean canOperateOnVolume(Volume volume); diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index 67b60623a6a..a87f542dcba 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -53,6 +53,7 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DownloadSnapshotFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; @@ -109,6 +110,7 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.storage.template.TemplateConstants; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; @@ -323,20 +325,6 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } - @Override - public void deleteSnapshotsDirForVolume(String secondaryStoragePoolUrl, Long dcId, Long accountId, Long volumeId) { - DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(secondaryStoragePoolUrl, dcId, accountId, volumeId); - try { - DataStore store = this.dataStoreMgr.getImageStore(dcId); - EndPoint ep = _epSelector.select(store); - Answer ans = ep.sendMessage(cmd); - if (ans == null || !ans.getResult()) { - s_logger.warn("DeleteSnapshotsDirCommand failed due to " + ans.getDetails() + " volume id: " + volumeId); - } - } catch (Exception e) { - s_logger.warn("DeleteSnapshotsDirCommand failed due to" + e.toString() + " volume id: " + volumeId); - } - } @Override public Snapshot backupSnapshot(Long snapshotId) { @@ -689,8 +677,8 @@ public class SnapshotManagerImpl extends ManagerBase implements SnapshotManager, } List ssHosts = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(dcId)); for (DataStore ssHost : ssHosts) { - DeleteSnapshotBackupCommand cmd = new DeleteSnapshotBackupCommand(ssHost.getTO(), ssHost.getUri(), dcId, accountId, volumeId, "", - true); + String snapshotDir = TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + accountId + "/" + volumeId; + DeleteSnapshotsDirCommand cmd = new DeleteSnapshotsDirCommand(ssHost.getTO(), snapshotDir); EndPoint ep = _epSelector.select(ssHost); Answer answer = ep.sendMessage(cmd); if ((answer != null) && answer.getResult()) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 27a15ccdd83..d6a2af4d5c7 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -68,6 +68,7 @@ import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DownloadSnapshotFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; @@ -211,6 +212,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((DownloadSnapshotFromS3Command) cmd); } else if (cmd instanceof DeleteSnapshotBackupCommand) { return execute((DeleteSnapshotBackupCommand) cmd); + } else if (cmd instanceof DeleteSnapshotBackupCommand2) { + return execute((DeleteSnapshotBackupCommand2) cmd); } else if (cmd instanceof DeleteSnapshotsDirCommand) { return execute((DeleteSnapshotsDirCommand) cmd); } else if (cmd instanceof DownloadTemplateFromSwiftToSecondaryStorageCommand) { @@ -838,28 +841,78 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return null; } - // TODO: this DeleteSnapshotsDirCommand should be removed after - // SnapshotManager refactor, this is used to delete those snapshot directory - // in the cachestorage. This should be able to be done through - // DeleteSnapshotBackupCommand with deleteAll flag set to true. public Answer execute(DeleteSnapshotsDirCommand cmd) { - String secondaryStorageUrl = cmd.getSecondaryStorageUrl(); - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); - try { - String parent = getRootDir(secondaryStorageUrl); - String lPath = parent + "/snapshots/" + String.valueOf(accountId) + "/" + String.valueOf(volumeId) + "/*"; + DataStoreTO dstore = cmd.getDataStore(); + if (dstore instanceof NfsTO) { + NfsTO nfs = (NfsTO) dstore; + String relativeSnapshotPath = cmd.getDirectory(); + String parent = getRootDir(nfs.getUrl()); + + if (relativeSnapshotPath.startsWith(File.separator)) { + relativeSnapshotPath = relativeSnapshotPath.substring(1); + } + + if (!parent.endsWith(File.separator)) { + parent += File.separator; + } + String absoluteSnapshotPath = parent + relativeSnapshotPath; + File snapshotDir = new File(absoluteSnapshotPath); + String details = null; + if (!snapshotDir.exists()) { + details = "snapshot directory " + snapshotDir.getName() + " doesn't exist"; + s_logger.debug(details); + return new Answer(cmd, true, details); + } + // delete all files in the directory + String lPath = absoluteSnapshotPath + "/*"; String result = deleteLocalFile(lPath); if (result != null) { String errMsg = "failed to delete all snapshots " + lPath + " , err=" + result; s_logger.warn(errMsg); return new Answer(cmd, false, errMsg); } - return new Answer(cmd, true, "success"); - } catch (Exception e) { - String errMsg = cmd + " Command failed due to " + e.toString(); - s_logger.warn(errMsg, e); - return new Answer(cmd, false, errMsg); + // delete the directory + if (!snapshotDir.delete()) { + details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath; + s_logger.debug(details); + return new Answer(cmd, false, details); + } + return new Answer(cmd, true, null); + } else if (dstore instanceof S3TO) { + final S3TO s3 = (S3TO) dstore; + final String path = cmd.getDirectory(); + final String bucket = s3.getBucketName(); + try { + S3Utils.deleteDirectory(s3, bucket, path); + return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); + } catch (Exception e) { + final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, + bucket, e.getMessage()); + s_logger.error(errorMessage, e); + return new Answer(cmd, false, errorMessage); + } + } else if (dstore instanceof SwiftTO) { + String path = cmd.getDirectory(); + String volumeId = StringUtils.substringAfterLast(path, "/"); // assuming + // that + // the + // filename + // is + // the + // last + // section + // in + // the + // path + String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId.toString(), ""); + if (result != null) { + String errMsg = "failed to delete snapshot for volume " + volumeId + " , err=" + result; + s_logger.warn(errMsg); + return new Answer(cmd, false, errMsg); + } + return new Answer(cmd, true, "Deleted snapshot " + path + " from swift"); + } else { + return new Answer(cmd, false, "Unsupported image data store: " + dstore); } } @@ -1183,6 +1236,74 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join("_", "SNAPSHOT", accountId, volumeId); } + protected Answer execute(final DeleteSnapshotBackupCommand2 cmd) { + DataStoreTO dstore = cmd.getDataStore(); + if (dstore instanceof NfsTO) { + NfsTO nfs = (NfsTO) dstore; + String relativeSnapshotPath = cmd.getSnapshotPath(); + String parent = getRootDir(nfs.getUrl()); + + if (relativeSnapshotPath.startsWith(File.separator)) { + relativeSnapshotPath = relativeSnapshotPath.substring(1); + } + + if (!parent.endsWith(File.separator)) { + parent += File.separator; + } + String absoluteSnapshotPath = parent + relativeSnapshotPath; + File snapshot = new File(absoluteSnapshotPath); + String details = null; + if (!snapshot.exists()) { + details = "snapshot file " + snapshot.getName() + " doesn't exist"; + s_logger.debug(details); + return new Answer(cmd, true, details); + } + + if (!snapshot.delete()) { + return new Answer(cmd, false, "Unable to delete file " + snapshot.getName() + " under install path " + relativeSnapshotPath); + } + + return new Answer(cmd, true, null); + } else if (dstore instanceof S3TO) { + final S3TO s3 = (S3TO) dstore; + final String path = cmd.getSnapshotPath(); + final String bucket = s3.getBucketName(); + try { + S3Utils.deleteObject(s3, bucket, path); + return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); + } catch (Exception e) { + final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, + bucket, e.getMessage()); + s_logger.error(errorMessage, e); + return new Answer(cmd, false, errorMessage); + } + } else if (dstore instanceof SwiftTO) { + String path = cmd.getSnapshotPath(); + String filename = StringUtils.substringAfterLast(path, "/"); // assuming + // that + // the + // filename + // is + // the + // last + // section + // in + // the + // path + String volumeId = StringUtils.substringAfterLast(StringUtils.substringBeforeLast(path, "/"), "/"); + String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId, filename); + if (result != null) { + String errMsg = "failed to delete snapshot " + filename + " , err=" + result; + s_logger.warn(errMsg); + return new Answer(cmd, false, errMsg); + } + return new Answer(cmd, true, "Deleted snapshot " + path + " from swift"); + } else { + return new Answer(cmd, false, "Unsupported image data store: " + dstore); + } + + } + protected Answer execute(final DeleteSnapshotBackupCommand cmd) { Long accountId = cmd.getAccountId(); Long volumeId = cmd.getVolumeId(); @@ -1660,7 +1781,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.warn(errMsg); return new Answer(cmd, false, errMsg); } - return new Answer(cmd, false, "Swift is not currently support DeleteVolumeCommand"); + return new Answer(cmd, true, "Deleted volume " + path + " from swift"); } else { return new Answer(cmd, false, "Unsupported image data store: " + dstore); } From bc91e7692decfa35bbcfb38b8059a47ced1d60d2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 29 May 2013 15:22:04 -0700 Subject: [PATCH 264/303] Fix build. --- .../storage/test/volumeServiceTest.java | 1 - .../resource/LibvirtComputingResource.java | 29 ------------------- 2 files changed, 30 deletions(-) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 243d3b2028f..4e221010190 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -44,7 +44,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; -import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index ee8531b5ca9..50187cebd4f 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -2122,35 +2122,6 @@ ServerResource { return new DeleteSnapshotBackupAnswer(cmd, true, null); } - protected Answer execute(DeleteSnapshotsDirCommand cmd) { - Long dcId = cmd.getDcId(); - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); - KVMStoragePool secondaryStoragePool = null; - try { - secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd - .getSecondaryStorageUrl()); - - String ssPmountPath = secondaryStoragePool.getLocalPath(); - String snapshotDestPath = ssPmountPath + File.separator - + "snapshots" + File.separator + dcId + File.separator - + accountId + File.separator + volumeId; - - final Script command = new Script(_manageSnapshotPath, - _cmdsTimeout, s_logger); - command.add("-d", snapshotDestPath); - command.add("-f"); - command.execute(); - } catch (CloudRuntimeException e) { - return new Answer(cmd, false, e.toString()); - } finally { - if (secondaryStoragePool != null) { - _storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(),secondaryStoragePool.getUuid()); - } - - } - return new Answer(cmd, true, null); - } protected CreateVolumeFromSnapshotAnswer execute( final CreateVolumeFromSnapshotCommand cmd) { From e51adc3b7d0af7f8c127320dab4ce46f93bccf8c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 29 May 2013 15:47:39 -0700 Subject: [PATCH 265/303] CLOUDSTACK-2673: Failed to deploy guest vm using ISO with S3 being the storage provider. --- .../com/cloud/template/TemplateManager.java | 3 + .../cloud/template/TemplateManagerImpl.java | 944 +++++++++--------- .../src/com/cloud/vm/UserVmManagerImpl.java | 15 +- 3 files changed, 498 insertions(+), 464 deletions(-) diff --git a/server/src/com/cloud/template/TemplateManager.java b/server/src/com/cloud/template/TemplateManager.java index af71d30d9e9..8427fa92c7b 100755 --- a/server/src/com/cloud/template/TemplateManager.java +++ b/server/src/com/cloud/template/TemplateManager.java @@ -19,6 +19,7 @@ package com.cloud.template; import java.util.List; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; @@ -108,6 +109,8 @@ public interface TemplateManager extends TemplateApiService{ List getImageStoreByTemplate(long templateId, Long zoneId); + TemplateInfo prepareIso(long isoId, long dcId); + diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 96430afe38b..94193d5c5a3 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -198,31 +198,51 @@ import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @Component -@Local(value={TemplateManager.class, TemplateApiService.class}) +@Local(value = { TemplateManager.class, TemplateApiService.class }) public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateApiService { private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class); - @Inject VMTemplateDao _tmpltDao; - @Inject TemplateDataStoreDao _tmplStoreDao; - @Inject VMTemplatePoolDao _tmpltPoolDao; - @Inject VMTemplateZoneDao _tmpltZoneDao; + @Inject + VMTemplateDao _tmpltDao; + @Inject + TemplateDataStoreDao _tmplStoreDao; + @Inject + VMTemplatePoolDao _tmpltPoolDao; + @Inject + VMTemplateZoneDao _tmpltZoneDao; @Inject protected VMTemplateDetailsDao _templateDetailsDao; - @Inject VMInstanceDao _vmInstanceDao; - @Inject PrimaryDataStoreDao _poolDao; - @Inject StoragePoolHostDao _poolHostDao; - @Inject EventDao _eventDao; - @Inject DownloadMonitor _downloadMonitor; - @Inject UploadMonitor _uploadMonitor; - @Inject UserAccountDao _userAccountDao; - @Inject AccountDao _accountDao; - @Inject UserDao _userDao; - @Inject AgentManager _agentMgr; - @Inject AccountManager _accountMgr; - @Inject HostDao _hostDao; - @Inject DataCenterDao _dcDao; - @Inject UserVmDao _userVmDao; - @Inject VolumeDao _volumeDao; - @Inject SnapshotDao _snapshotDao; + @Inject + VMInstanceDao _vmInstanceDao; + @Inject + PrimaryDataStoreDao _poolDao; + @Inject + StoragePoolHostDao _poolHostDao; + @Inject + EventDao _eventDao; + @Inject + DownloadMonitor _downloadMonitor; + @Inject + UploadMonitor _uploadMonitor; + @Inject + UserAccountDao _userAccountDao; + @Inject + AccountDao _accountDao; + @Inject + UserDao _userDao; + @Inject + AgentManager _agentMgr; + @Inject + AccountManager _accountMgr; + @Inject + HostDao _hostDao; + @Inject + DataCenterDao _dcDao; + @Inject + UserVmDao _userVmDao; + @Inject + VolumeDao _volumeDao; + @Inject + SnapshotDao _snapshotDao; @Inject VMTemplateSwiftDao _tmpltSwiftDao; @Inject @@ -231,21 +251,33 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, ConfigurationDao _configDao; @Inject ClusterDao _clusterDao; - @Inject DomainDao _domainDao; - @Inject UploadDao _uploadDao; + @Inject + DomainDao _domainDao; + @Inject + UploadDao _uploadDao; @Inject protected GuestOSDao _guestOSDao; long _routerTemplateId = -1; - @Inject StorageManager _storageMgr; - @Inject AsyncJobManager _asyncMgr; - @Inject UserVmManager _vmMgr; - @Inject UsageEventDao _usageEventDao; - @Inject HypervisorGuruManager _hvGuruMgr; - @Inject AccountService _accountService; - @Inject ResourceLimitService _resourceLimitMgr; - @Inject SecondaryStorageVmManager _ssvmMgr; - @Inject LaunchPermissionDao _launchPermissionDao; - @Inject ProjectManager _projectMgr; + @Inject + StorageManager _storageMgr; + @Inject + AsyncJobManager _asyncMgr; + @Inject + UserVmManager _vmMgr; + @Inject + UsageEventDao _usageEventDao; + @Inject + HypervisorGuruManager _hvGuruMgr; + @Inject + AccountService _accountService; + @Inject + ResourceLimitService _resourceLimitMgr; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + LaunchPermissionDao _launchPermissionDao; + @Inject + ProjectManager _projectMgr; @Inject VolumeDataFactory _volFactory; @Inject @@ -258,10 +290,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, DataStoreManager _dataStoreMgr; @Inject protected ResourceManager _resourceMgr; - @Inject VolumeManager _volumeMgr; - @Inject ImageStoreDao _imageStoreDao; - @Inject EndPointSelector _epSelector; - @Inject UserVmJoinDao _userVmJoinDao; + @Inject + VolumeManager _volumeMgr; + @Inject + ImageStoreDao _imageStoreDao; + @Inject + EndPointSelector _epSelector; + @Inject + UserVmJoinDao _userVmJoinDao; @Inject ConfigurationServer _configServer; @@ -279,55 +315,54 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Inject EndPointSelector selector; - private TemplateAdapter getAdapter(HypervisorType type) { - TemplateAdapter adapter = null; - if (type == HypervisorType.BareMetal) { - adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName()); - } else { - // see HypervisorTemplateAdapter - adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName()); - } + TemplateAdapter adapter = null; + if (type == HypervisorType.BareMetal) { + adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.BareMetal.getName()); + } else { + // see HypervisorTemplateAdapter + adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName()); + } - if (adapter == null) { - throw new CloudRuntimeException("Cannot find template adapter for " + type.toString()); - } + if (adapter == null) { + throw new CloudRuntimeException("Cannot find template adapter for " + type.toString()); + } - return adapter; + return adapter; } @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso") - public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException{ - TemplateAdapter adapter = getAdapter(HypervisorType.None); - TemplateProfile profile = adapter.prepare(cmd); - VMTemplateVO template = adapter.create(profile); + public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException { + TemplateAdapter adapter = getAdapter(HypervisorType.None); + TemplateProfile profile = adapter.prepare(cmd); + VMTemplateVO template = adapter.create(profile); - if (template != null){ - return template; - }else { - throw new CloudRuntimeException("Failed to create ISO"); + if (template != null) { + return template; + } else { + throw new CloudRuntimeException("Failed to create ISO"); } } @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template") - public VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException{ - if(cmd.getTemplateTag() != null){ + public VirtualMachineTemplate registerTemplate(RegisterTemplateCmd cmd) throws URISyntaxException, ResourceAllocationException { + if (cmd.getTemplateTag() != null) { Account account = UserContext.current().getCaller(); - if(!_accountService.isRootAdmin(account.getType())){ + if (!_accountService.isRootAdmin(account.getType())) { throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied"); } } - TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor())); - TemplateProfile profile = adapter.prepare(cmd); - VMTemplateVO template = adapter.create(profile); + TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor())); + TemplateProfile profile = adapter.prepare(cmd); + VMTemplateVO template = adapter.create(profile); - if (template != null){ - return template; - }else { - throw new CloudRuntimeException("Failed to create a template"); + if (template != null) { + return template; + } else { + throw new CloudRuntimeException("Failed to create a template"); } } @@ -359,10 +394,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // FIXME: async job needs fixing Pair uploadPair = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr); - if (uploadPair != null){ - return uploadPair; - }else { - throw new CloudRuntimeException("Failed to extract the iso"); + if (uploadPair != null) { + return uploadPair; + } else { + throw new CloudRuntimeException("Failed to extract the iso"); } } @@ -385,32 +420,33 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // FIXME: async job needs fixing Pair uploadPair = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr); - if (uploadPair != null){ - return uploadPair; - }else { - throw new CloudRuntimeException("Failed to extract the teamplate"); + if (uploadPair != null) { + return uploadPair; + } else { + throw new CloudRuntimeException("Failed to extract the teamplate"); } } @Override public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) { - VMTemplateVO vmTemplate = _tmpltDao.findById(templateId); - if(vmTemplate == null) - throw new InvalidParameterValueException("Unable to find template id=" + templateId); + VMTemplateVO vmTemplate = _tmpltDao.findById(templateId); + if (vmTemplate == null) + throw new InvalidParameterValueException("Unable to find template id=" + templateId); - _accountMgr.checkAccess(UserContext.current().getCaller(), AccessType.ModifyEntry, true, vmTemplate); + _accountMgr.checkAccess(UserContext.current().getCaller(), AccessType.ModifyEntry, true, vmTemplate); - prepareTemplateInAllStoragePools(vmTemplate, zoneId); - return vmTemplate; + prepareTemplateInAllStoragePools(vmTemplate, zoneId); + return vmTemplate; } - private Pair extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, AsyncJobVO job, AsyncJobManager mgr) { + private Pair extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, + AsyncJobVO job, AsyncJobManager mgr) { String desc = Upload.Type.TEMPLATE.toString(); if (isISO) { desc = Upload.Type.ISO.toString(); } - eventId = eventId == null ? 0:eventId; + eventId = eventId == null ? 0 : eventId; if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) { throw new PermissionDeniedException("Extraction has been disabled by admin"); @@ -418,26 +454,27 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, VMTemplateVO template = _tmpltDao.findById(templateId); if (template == null || template.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find " +desc+ " with id " + templateId); + throw new InvalidParameterValueException("Unable to find " + desc + " with id " + templateId); } - if (template.getTemplateType() == Storage.TemplateType.SYSTEM){ - throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template"); - } else if (template.getTemplateType() == Storage.TemplateType.PERHOST){ - throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM"); + if (template.getTemplateType() == Storage.TemplateType.SYSTEM) { + throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + + " as it is a default System template"); + } else if (template.getTemplateType() == Storage.TemplateType.PERHOST) { + throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + + " as it resides on host and not on SSVM"); } if (isISO) { - if (template.getFormat() != ImageFormat.ISO ){ + if (template.getFormat() != ImageFormat.ISO) { throw new InvalidParameterValueException("Unsupported format, could not extract the ISO"); } } else { - if (template.getFormat() == ImageFormat.ISO ){ + if (template.getFormat() == ImageFormat.ISO) { throw new InvalidParameterValueException("Unsupported format, could not extract the template"); } } - if (zoneId != null && _dcDao.findById(zoneId) == null) { throw new IllegalArgumentException("Please specify a valid zone."); } @@ -453,11 +490,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateDataStoreVO tmpltStoreRef = null; ImageStoreEntity tmpltStore = null; if (ssStores != null) { - for(DataStore store: ssStores){ + for (DataStore store : ssStores) { tmpltStoreRef = this._tmplStoreDao.findByStoreTemplate(store.getId(), templateId); - if (tmpltStoreRef != null){ + if (tmpltStoreRef != null) { if (tmpltStoreRef.getDownloadState() == com.cloud.storage.VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - tmpltStore = (ImageStoreEntity)store; + tmpltStore = (ImageStoreEntity) store; break; } } @@ -468,49 +505,50 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); } - if (tmpltStore.getProviderName().equalsIgnoreCase("Swift")){ + if (tmpltStore.getProviderName().equalsIgnoreCase("Swift")) { throw new UnsupportedServiceException("ExtractTemplate is not yet supported for Swift image store provider"); } - if ( tmpltStore.getProviderName().equalsIgnoreCase("S3")){ - // for S3, no need to do anything, just return template url for extract template. but we need to set object acl as public_read to + if (tmpltStore.getProviderName().equalsIgnoreCase("S3")) { + // for S3, no need to do anything, just return template url for + // extract template. but we need to set object acl as public_read to // make the url accessible - S3TO s3 = (S3TO)tmpltStore.getTO(); - String key = tmpltStoreRef.getLocalDownloadPath(); - try{ - S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); - } - catch (Exception ex){ - s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); - throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); - } - // construct the url from s3 - StringBuffer s3url = new StringBuffer(); - s3url.append(s3.isHttps() ? "https://" : "http://"); - s3url.append(s3.getEndPoint()); - s3url.append("/"); - s3url.append(s3.getBucketName()); - s3url.append("/"); - s3url.append(key); + S3TO s3 = (S3TO) tmpltStore.getTO(); + String key = tmpltStoreRef.getLocalDownloadPath(); + try { + S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); + } catch (Exception ex) { + s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); + throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); + } + // construct the url from s3 + StringBuffer s3url = new StringBuffer(); + s3url.append(s3.isHttps() ? "https://" : "http://"); + s3url.append(s3.getEndPoint()); + s3url.append("/"); + s3url.append(s3.getBucketName()); + s3url.append("/"); + s3url.append(key); - return new Pair(null, s3url.toString()); + return new Pair(null, s3url.toString()); } - // for NFS image store case, control will come here Upload.Mode extractMode; - if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){ - throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD); + if (mode == null + || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString()))) { + throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: " + Upload.Mode.FTP_UPLOAD + ", " + + Upload.Mode.HTTP_DOWNLOAD); } else { extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; } - if (extractMode == Upload.Mode.FTP_UPLOAD){ + if (extractMode == Upload.Mode.FTP_UPLOAD) { URI uri = null; try { uri = new URI(url); - if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp") )) { - throw new InvalidParameterValueException("Unsupported scheme for url: " + url); + if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp"))) { + throw new InvalidParameterValueException("Unsupported scheme for url: " + url); } } catch (Exception ex) { throw new InvalidParameterValueException("Invalid url given: " + url); @@ -519,7 +557,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, String host = uri.getHost(); try { InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress() ) { + if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { throw new InvalidParameterValueException("Illegal host specified in url"); } if (hostAddr instanceof Inet6Address) { @@ -529,53 +567,55 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("Unable to resolve " + host); } - if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE) ){ - throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same"); + if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE)) { + throw new IllegalArgumentException(template.getName() + + " upload is in progress. Please wait for some time to schedule another upload for the same"); } return new Pair(_uploadMonitor.extractTemplate(template, url, tmpltStoreRef, zoneId, eventId, job.getId(), mgr), null); } UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltStoreRef, zoneId, eventId); - if (vo != null){ + if (vo != null) { return new Pair(vo.getId(), null); - }else{ + } else { return null; } } public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) { - List pools = _poolDao.listByStatus(StoragePoolStatus.Up); - for(final StoragePoolVO pool : pools) { - if(pool.getDataCenterId() == zoneId) { - s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); - this._preloadExecutor.execute(new Runnable() { - @Override + List pools = _poolDao.listByStatus(StoragePoolStatus.Up); + for (final StoragePoolVO pool : pools) { + if (pool.getDataCenterId() == zoneId) { + s_logger.info("Schedule to preload template " + template.getId() + " into primary storage " + pool.getId()); + this._preloadExecutor.execute(new Runnable() { + @Override public void run() { - try { - reallyRun(); - } catch(Throwable e) { - s_logger.warn("Unexpected exception ", e); - } - } + try { + reallyRun(); + } catch (Throwable e) { + s_logger.warn("Unexpected exception ", e); + } + } - private void reallyRun() { - s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId()); - StoragePool pol = (StoragePool)_dataStoreMgr.getPrimaryDataStore(pool.getId()); - prepareTemplateForCreate(template, pol); - s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId()); - } - }); - } else { - s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + pool.getDataCenterId() + " is "); - } - } + private void reallyRun() { + s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId()); + StoragePool pol = (StoragePool) _dataStoreMgr.getPrimaryDataStore(pool.getId()); + prepareTemplateForCreate(template, pol); + s_logger.info("End of preloading template " + template.getId() + " into primary storage " + pool.getId()); + } + }); + } else { + s_logger.info("Skip loading template " + template.getId() + " into primary storage " + pool.getId() + " as pool zone " + + pool.getDataCenterId() + " is "); + } + } } - - @Override @DB + @Override + @DB public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) { - VMTemplateVO template = _tmpltDao.findById(templ.getId(), true); + VMTemplateVO template = _tmpltDao.findById(templ.getId(), true); long poolId = pool.getId(); long templateId = template.getId(); @@ -584,30 +624,31 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId); if (templateStoragePoolRef != null) { - templateStoragePoolRef.setMarkedForGC(false); + templateStoragePoolRef.setMarkedForGC(false); _tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef); if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId); - } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId); + } - return templateStoragePoolRef; - } + return templateStoragePoolRef; + } } - templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, pool.getDataCenterId(), + VMTemplateStorageResourceAssoc.Status.DOWNLOADED); if (templateStoreRef == null) { s_logger.error("Unable to find a secondary storage host who has completely downloaded the template."); return null; } List vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up); - if (vos == null || vos.isEmpty()){ - throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool"); + if (vos == null || vos.isEmpty()) { + throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + + " since there is no host in the Up state connected to this pool"); } - if (templateStoragePoolRef == null) { if (s_logger.isDebugEnabled()) { s_logger.debug("Downloading template " + templateId + " to pool " + poolId); @@ -624,8 +665,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } return _tmpltPoolDao.findByPoolTemplate(poolId, templateId); - } - catch (Exception ex) { + } catch (Exception ex) { s_logger.debug("failed to copy template from image store:" + srcSecStore.getName() + " to primary storage"); } } @@ -633,12 +673,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return null; } - @Override public String getChecksum(DataStore store, String templatePath) { EndPoint ep = _epSelector.select(store); - ComputeChecksumCommand cmd = new ComputeChecksumCommand( - store.getTO(), templatePath); + ComputeChecksumCommand cmd = new ComputeChecksumCommand(store.getTO(), templatePath); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { return answer.getDetails(); @@ -646,22 +684,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return null; } - - @Override @DB public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) { - // have to use the same lock that prepareTemplateForCreate use to maintain state consistency - VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200); + // have to use the same lock that prepareTemplateForCreate use to + // maintain state consistency + VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200); if (templateStoragePoolRef == null) { - s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId); + s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId); return false; } try { - templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED); - _tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef); + templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED); + _tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef); } finally { _tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId); } @@ -671,12 +708,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override @DB - public boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException { + public boolean copy(long userId, VMTemplateVO template, DataStore srcSecStore, DataCenterVO dstZone) throws StorageUnavailableException, + ResourceAllocationException { long tmpltId = template.getId(); long dstZoneId = dstZone.getId(); // find all eligible image stores for the destination zone List dstSecStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId)); - if (dstSecStores == null || dstSecStores.isEmpty() ) { + if (dstSecStores == null || dstSecStores.isEmpty()) { throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId()); } AccountVO account = _accountDao.findById(template.getAccountId()); @@ -689,7 +727,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // Event details String copyEventType; String createEventType; - if (template.getFormat().equals(ImageFormat.ISO)){ + if (template.getFormat().equals(ImageFormat.ISO)) { copyEventType = EventTypes.EVENT_ISO_COPY; createEventType = EventTypes.EVENT_ISO_CREATE; } else { @@ -733,19 +771,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } - - - @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true) public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException { - Long templateId = cmd.getId(); - Long userId = UserContext.current().getCallerUserId(); - Long sourceZoneId = cmd.getSourceZoneId(); - Long destZoneId = cmd.getDestinationZoneId(); - Account caller = UserContext.current().getCaller(); + Long templateId = cmd.getId(); + Long userId = UserContext.current().getCallerUserId(); + Long sourceZoneId = cmd.getSourceZoneId(); + Long destZoneId = cmd.getDestinationZoneId(); + Account caller = UserContext.current().getCaller(); - //Verify parameters + // Verify parameters if (sourceZoneId.equals(destZoneId)) { throw new InvalidParameterValueException("Please specify different source and destination zones."); } @@ -766,16 +801,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } DataStore dstSecStore = getImageStore(destZoneId, templateId); - if ( dstSecStore != null ) { - s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId + " , don't need to copy"); + if (dstSecStore != null) { + s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecStore.getName() + " in zone " + destZoneId + + " , don't need to copy"); return template; } DataStore srcSecStore = getImageStore(sourceZoneId, templateId); - if ( srcSecStore == null ) { - throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId ); + if (srcSecStore == null) { + throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId); } - if ( srcSecStore.getScope().getScopeType() == ScopeType.REGION){ + if (srcSecStore.getScope().getScopeType() == ScopeType.REGION) { s_logger.debug("Template " + templateId + " is in region-wide secondary storage " + dstSecStore.getName() + " , don't need to copy"); return template; } @@ -784,60 +820,60 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, boolean success = copy(userId, template, srcSecStore, dstZone); - if (success){ - return template; - }else { - throw new CloudRuntimeException("Failed to copy template"); + if (success) { + return template; + } else { + throw new CloudRuntimeException("Failed to copy template"); } } @Override public boolean delete(long userId, long templateId, Long zoneId) { - VMTemplateVO template = _tmpltDao.findById(templateId); - if (template == null || template.getRemoved() != null) { - throw new InvalidParameterValueException("Please specify a valid template."); - } + VMTemplateVO template = _tmpltDao.findById(templateId); + if (template == null || template.getRemoved() != null) { + throw new InvalidParameterValueException("Please specify a valid template."); + } - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); - return adapter.delete(new TemplateProfile(userId, template, zoneId)); + TemplateAdapter adapter = getAdapter(template.getHypervisorType()); + return adapter.delete(new TemplateProfile(userId, template, zoneId)); } @Override public List getUnusedTemplatesInPool(StoragePoolVO pool) { - List unusedTemplatesInPool = new ArrayList(); - List allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId()); + List unusedTemplatesInPool = new ArrayList(); + List allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId()); - for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) { - VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); + for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) { + VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); - // If this is a routing template, consider it in use - if (template.getTemplateType() == TemplateType.SYSTEM) { - continue; - } + // If this is a routing template, consider it in use + if (template.getTemplateType() == TemplateType.SYSTEM) { + continue; + } - // If the template is not yet downloaded to the pool, consider it in use - if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) { - continue; - } + // If the template is not yet downloaded to the pool, consider it in + // use + if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) { + continue; + } - if (template.getFormat() != ImageFormat.ISO && !_volumeDao.isAnyVolumeActivelyUsingTemplateOnPool(template.getId(), pool.getId())) { + if (template.getFormat() != ImageFormat.ISO && !_volumeDao.isAnyVolumeActivelyUsingTemplateOnPool(template.getId(), pool.getId())) { unusedTemplatesInPool.add(templatePoolVO); - } - } + } + } - return unusedTemplatesInPool; - } + return unusedTemplatesInPool; + } @Override public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) { - StoragePool pool = (StoragePool)this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); - VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); + StoragePool pool = (StoragePool) this._dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId()); + VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId()); - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Evicting " + templatePoolVO); - } - DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Evicting " + templatePoolVO); + } + DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO); try { Answer answer = _storageMgr.sendToPool(pool, cmd); @@ -851,11 +887,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.info("Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName()); } } catch (StorageUnavailableException e) { - s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: " + pool.getName()); + s_logger.info("Storage is unavailable currently. Will retry evicte template: " + template.getName() + " from storage pool: " + + pool.getName()); } - } - + } @Override public boolean start() { @@ -876,59 +912,64 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, String value = _configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); - String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString()); - _disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction); - + String disableExtraction = _configDao.getValue(Config.DisableExtraction.toString()); + _disableExtraction = (disableExtraction == null) ? false : Boolean.parseBoolean(disableExtraction); _storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); _preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader")); - return true; } protected TemplateManagerImpl() { } - @Override - public boolean templateIsDeleteable(VMTemplateHostVO templateHostRef) { - VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateHostRef.getTemplateId()); - long templateId = template.getId(); - HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId()); - long zoneId = secondaryStorageHost.getDataCenterId(); - DataCenterVO zone = _dcDao.findById(zoneId); + @Override + public boolean templateIsDeleteable(VMTemplateHostVO templateHostRef) { + VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateHostRef.getTemplateId()); + long templateId = template.getId(); + HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId()); + long zoneId = secondaryStorageHost.getDataCenterId(); + DataCenterVO zone = _dcDao.findById(zoneId); - // Check if there are VMs running in the template host ref's zone that use the template - List nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId); + // Check if there are VMs running in the template host ref's zone that + // use the template + List nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId); - if (!nonExpungedVms.isEmpty()) { - s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are non-expunged VMs deployed from this template."); - return false; - } - List userVmUsingIso = _userVmDao.listByIsoId(templateId); - //check if there is any VM using this ISO. - if (!userVmUsingIso.isEmpty()) { - s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs"); - return false; - } - // Check if there are any snapshots for the template in the template host ref's zone - List volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId); - for (VolumeVO volume : volumes) { - List snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1"); - if (!snapshots.isEmpty()) { - s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are 2.1 snapshots using this template."); - return false; - } - } + if (!nonExpungedVms.isEmpty()) { + s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + + " is not deleteable because there are non-expunged VMs deployed from this template."); + return false; + } + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + // check if there is any VM using this ISO. + if (!userVmUsingIso.isEmpty()) { + s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + + userVmUsingIso.size() + " VMs"); + return false; + } + // Check if there are any snapshots for the template in the template + // host ref's zone + List volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId); + for (VolumeVO volume : volumes) { + List snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1"); + if (!snapshots.isEmpty()) { + s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + + " is not deleteable because there are 2.1 snapshots using this template."); + return false; + } + } - return true; - } + return true; + } @Override public boolean templateIsDeleteable(long templateId) { List userVmUsingIso = _userVmJoinDao.listActiveByIsoId(templateId); - //check if there is any Vm using this ISO. We only need to check the case where templateId is an ISO since - // VM can be launched from ISO in secondary storage, while template will always be copied to + // check if there is any Vm using this ISO. We only need to check the + // case where templateId is an ISO since + // VM can be launched from ISO in secondary storage, while template will + // always be copied to // primary storage before deploying VM. if (!userVmUsingIso.isEmpty()) { s_logger.debug("ISO " + templateId + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs"); @@ -938,16 +979,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return true; } - @Override + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true) - public boolean detachIso(long vmId) { + public boolean detachIso(long vmId) { Account caller = UserContext.current().getCaller(); Long userId = UserContext.current().getCallerUserId(); // Verify input parameters UserVmVO vmInstanceCheck = _userVmDao.findById(vmId); if (vmInstanceCheck == null) { - throw new InvalidParameterValueException ("Unable to find a virtual machine with id " + vmId); + throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId); } UserVm userVM = _userVmDao.findById(vmId); @@ -961,66 +1002,90 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (isoId == null) { throw new InvalidParameterValueException("The specified VM has no ISO attached to it."); } - UserContext.current().setEventDetails("Vm Id: " +vmId+ " ISO Id: "+isoId); + UserContext.current().setEventDetails("Vm Id: " + vmId + " ISO Id: " + isoId); State vmState = userVM.getState(); if (vmState != State.Running && vmState != State.Stopped) { - throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); + throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); } - boolean result = attachISOToVM(vmId, userId, isoId, false); //attach=false => detach - if (result){ - return result; - }else { - throw new CloudRuntimeException("Failed to detach iso"); + boolean result = attachISOToVM(vmId, userId, isoId, false); // attach=false + // => detach + if (result) { + return result; + } else { + throw new CloudRuntimeException("Failed to detach iso"); } - } + } - @Override + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true) - public boolean attachIso(long isoId, long vmId) { + public boolean attachIso(long isoId, long vmId) { Account caller = UserContext.current().getCaller(); Long userId = UserContext.current().getCallerUserId(); - // Verify input parameters - UserVmVO vm = _userVmDao.findById(vmId); - if (vm == null) { + // Verify input parameters + UserVmVO vm = _userVmDao.findById(vmId); + if (vm == null) { throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId); } - VMTemplateVO iso = _tmpltDao.findById(isoId); - if (iso == null || iso.getRemoved() != null) { + VMTemplateVO iso = _tmpltDao.findById(isoId); + if (iso == null || iso.getRemoved() != null) { throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId); - } + } - //check permissions - //check if caller has access to VM and ISO - //and also check if the VM's owner has access to the ISO. + // check permissions + // check if caller has access to VM and ISO + // and also check if the VM's owner has access to the ISO. - _accountMgr.checkAccess(caller, null, false, iso, vm); + _accountMgr.checkAccess(caller, null, false, iso, vm); - Account vmOwner = _accountDao.findById(vm.getAccountId()); - _accountMgr.checkAccess(vmOwner, null, false, iso, vm); + Account vmOwner = _accountDao.findById(vm.getAccountId()); + _accountMgr.checkAccess(vmOwner, null, false, iso, vm); State vmState = vm.getState(); if (vmState != State.Running && vmState != State.Stopped) { - throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); + throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running."); } - if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer){ - throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType()); + if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer) { + throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType()); } - if("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) { - throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType()); + if ("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) { + throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType()); } boolean result = attachISOToVM(vmId, userId, isoId, true); - if (result){ - return result; - }else { - throw new CloudRuntimeException("Failed to attach iso"); + if (result) { + return result; + } else { + throw new CloudRuntimeException("Failed to attach iso"); } - } + } + + // for ISO, we need to consider whether to copy to cache storage or not if it is not on NFS, since our hypervisor resource always assumes that they are in NFS + @Override + public TemplateInfo prepareIso(long isoId, long dcId){ + TemplateInfo tmplt = this._tmplFactory.getTemplate(isoId, DataStoreRole.Image, dcId); + if (tmplt == null || tmplt.getFormat() != ImageFormat.ISO ) { + s_logger.warn("ISO: " + isoId + " does not exist in vm_template table"); + return null; + } + + if (tmplt.getDataStore() != null && !(tmplt.getDataStore().getTO() instanceof NfsTO)) { + // if it is s3, need to download into cache storage first + Scope destScope = new ZoneScope(dcId); + TemplateInfo cacheData = (TemplateInfo) cacheMgr.createCacheObject(tmplt, destScope); + if (cacheData == null) { + s_logger.error("Failed in copy iso from S3 to cache storage"); + return null; + } + return cacheData; + } else{ + return tmplt; + } + } private boolean attachISOToVM(long vmId, long isoId, boolean attach) { UserVmVO vm = this._userVmDao.findById(vmId); @@ -1030,20 +1095,9 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } else if (vm.getState() != State.Running) { return true; } - TemplateInfo tmplt = this._tmplFactory.getTemplate(isoId, DataStoreRole.Image, vm.getDataCenterId()); - if (tmplt == null) { - s_logger.warn("ISO: " + isoId + " does not exist"); - return false; - } - if (tmplt.getDataStore() != null && !(tmplt.getDataStore().getTO() instanceof NfsTO)) { - // if it is s3, need to download into cache storage first - Scope destScope = new ZoneScope(vm.getDataCenterId()); - TemplateInfo cacheData = (TemplateInfo) cacheMgr.createCacheObject(tmplt, destScope); - if (cacheData == null){ - s_logger.error("Failed in copy iso from S3 to cache storage"); - return false; - } - } + + // prepare ISO ready to mount on hypervisor resource level + TemplateInfo tmplt = prepareIso(isoId, vm.getDataCenterId()); String vmName = vm.getInstanceName(); @@ -1066,22 +1120,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) { - UserVmVO vm = _userVmDao.findById(vmId); - VMTemplateVO iso = _tmpltDao.findById(isoId); + UserVmVO vm = _userVmDao.findById(vmId); + VMTemplateVO iso = _tmpltDao.findById(isoId); boolean success = attachISOToVM(vmId, isoId, attach); - if ( success && attach) { - vm.setIsoId(iso.getId()); + if (success && attach) { + vm.setIsoId(iso.getId()); _userVmDao.update(vmId, vm); } - if ( success && !attach ) { + if (success && !attach) { vm.setIsoId(null); _userVmDao.update(vmId, vm); } return success; } - @Override + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true) public boolean deleteTemplate(DeleteTemplateCmd cmd) { Long templateId = cmd.getId(); @@ -1094,60 +1148,61 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - if (template.getFormat() == ImageFormat.ISO) { - throw new InvalidParameterValueException("Please specify a valid template."); - } + if (template.getFormat() == ImageFormat.ISO) { + throw new InvalidParameterValueException("Please specify a valid template."); + } - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); - TemplateProfile profile = adapter.prepareDelete(cmd); - return adapter.delete(profile); - } + TemplateAdapter adapter = getAdapter(template.getHypervisorType()); + TemplateProfile profile = adapter.prepareDelete(cmd); + return adapter.delete(profile); + } - @Override + @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true) public boolean deleteIso(DeleteIsoCmd cmd) { Long templateId = cmd.getId(); Account caller = UserContext.current().getCaller(); Long zoneId = cmd.getZoneId(); - VirtualMachineTemplate template = getTemplate(templateId);; + VirtualMachineTemplate template = getTemplate(templateId); + ; if (template == null) { throw new InvalidParameterValueException("unable to find iso with id " + templateId); } _accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template); - if (template.getFormat() != ImageFormat.ISO) { - throw new InvalidParameterValueException("Please specify a valid iso."); - } + if (template.getFormat() != ImageFormat.ISO) { + throw new InvalidParameterValueException("Please specify a valid iso."); + } - // check if there is any VM using this ISO. - if (!templateIsDeleteable(templateId)) { - throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); - } + // check if there is any VM using this ISO. + if (!templateIsDeleteable(templateId)) { + throw new InvalidParameterValueException("Unable to delete iso, as it's used by other vms"); + } - if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) { - throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); - } - TemplateAdapter adapter = getAdapter(template.getHypervisorType()); - TemplateProfile profile = adapter.prepareDelete(cmd); + if (zoneId != null && (this._dataStoreMgr.getImageStore(zoneId) == null)) { + throw new InvalidParameterValueException("Failed to find a secondary storage store in the specified zone."); + } + TemplateAdapter adapter = getAdapter(template.getHypervisorType()); + TemplateProfile profile = adapter.prepareDelete(cmd); boolean result = adapter.delete(profile); if (result) { return true; } else { - throw new CloudRuntimeException("Failed to delete ISO"); - } - } + throw new CloudRuntimeException("Failed to delete ISO"); + } + } - @Override - public VirtualMachineTemplate getTemplate(long templateId) { - VMTemplateVO template = _tmpltDao.findById(templateId); - if (template != null && template.getRemoved() == null) { - return template; - } + @Override + public VirtualMachineTemplate getTemplate(long templateId) { + VMTemplateVO template = _tmpltDao.findById(templateId); + if (template != null && template.getRemoved() == null) { + return template; + } - return null; - } + return null; + } @Override public List listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) { @@ -1230,7 +1285,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } - //convert projectIds to accountNames + // convert projectIds to accountNames if (projectIds != null) { for (Long projectId : projectIds) { Project project = _projectMgr.getProject(projectId); @@ -1258,22 +1313,27 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } boolean isAdmin = _accountMgr.isAdmin(caller.getType()); - // check configuration parameter(allow.public.user.templates) value for the template owner - boolean allowPublicUserTemplates = Boolean.valueOf(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), template.getAccountId())); + // check configuration parameter(allow.public.user.templates) value for + // the template owner + boolean allowPublicUserTemplates = Boolean.valueOf(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), + Config.ConfigurationParameterScope.account.toString(), template.getAccountId())); if (!isAdmin && !allowPublicUserTemplates && isPublic != null && isPublic) { throw new InvalidParameterValueException("Only private " + mediaType + "s can be created."); } if (accountNames != null) { - if ((operation == null) || (!operation.equalsIgnoreCase("add") && !operation.equalsIgnoreCase("remove") && !operation.equalsIgnoreCase("reset"))) { - throw new InvalidParameterValueException("Invalid operation on accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions." - + " Given operation is: '" + operation + "'"); + if ((operation == null) + || (!operation.equalsIgnoreCase("add") && !operation.equalsIgnoreCase("remove") && !operation.equalsIgnoreCase("reset"))) { + throw new InvalidParameterValueException( + "Invalid operation on accounts, the operation must be either 'add' or 'remove' in order to modify launch permissions." + + " Given operation is: '" + operation + "'"); } } Long accountId = template.getAccountId(); if (accountId == null) { - // if there is no owner of the template then it's probably already a public template (or domain private template) so + // if there is no owner of the template then it's probably already a + // public template (or domain private template) so // publishing to individual users is irrelevant throw new InvalidParameterValueException("Update template permissions is an invalid operation on template " + template.getName()); } @@ -1288,13 +1348,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, updatedTemplate.setFeatured(isFeatured.booleanValue()); } - if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {//Only ROOT admins allowed to change this powerful attribute - updatedTemplate.setExtractable(isExtractable.booleanValue()); - }else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute."); - } + if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {// Only + // ROOT + // admins + // allowed + // to + // change + // this + // powerful + // attribute + updatedTemplate.setExtractable(isExtractable.booleanValue()); + } else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { + throw new InvalidParameterValueException("Only ROOT admins are allowed to modify this attribute."); + } - _tmpltDao.update(template.getId(), updatedTemplate); + _tmpltDao.update(template.getId(), updatedTemplate); Long domainId = caller.getDomainId(); if ("add".equalsIgnoreCase(operation)) { @@ -1303,7 +1371,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Account permittedAccount = _accountDao.findActiveAccount(accountName, domainId); if (permittedAccount != null) { if (permittedAccount.getId() == caller.getId()) { - continue; // don't grant permission to the template owner, they implicitly have permission + continue; // don't grant permission to the template + // owner, they implicitly have permission } LaunchPermissionVO existingPermission = _launchPermissionDao.findByTemplateAndAccount(id, permittedAccount.getId()); if (existingPermission == null) { @@ -1312,8 +1381,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } } else { txn.rollback(); - throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + ", account not found. " - + "No permissions updated, please verify the account names and retry."); + throw new InvalidParameterValueException("Unable to grant a launch permission to account " + accountName + + ", account not found. " + "No permissions updated, please verify the account names and retry."); } } txn.commit(); @@ -1338,20 +1407,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return true; } - private String getRandomPrivateTemplateName() { return UUID.randomUUID().toString(); } - - - - @Override @DB @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", async = true) - public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) - throws CloudRuntimeException { + public VirtualMachineTemplate createPrivateTemplate(CreateTemplateCmd command) throws CloudRuntimeException { Long userId = UserContext.current().getCallerUserId(); if (userId == null) { userId = User.UID_SYSTEM; @@ -1384,11 +1447,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, SnapshotInfo snapInfo = this._snapshotFactory.getSnapshot(snapshotId, DataStoreRole.Image); future = this._tmpltSvr.createTemplateFromSnapshotAsync(snapInfo, tmplInfo, store.get(0)); } else if (volumeId != null) { - VolumeInfo volInfo = this._volFactory.getVolume(volumeId); - future = this._tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0)); + VolumeInfo volInfo = this._volFactory.getVolume(volumeId); + future = this._tmpltSvr.createTemplateFromVolumeAsync(volInfo, tmplInfo, store.get(0)); } else { - throw new CloudRuntimeException( - "Creating private Template need to specify snapshotId or volumeId"); + throw new CloudRuntimeException("Creating private Template need to specify snapshotId or volumeId"); } CommandResult result = null; @@ -1404,13 +1466,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, this._tmpltZoneDao.persist(templateZone); privateTemplate = this._tmpltDao.findById(templateId); - UsageEventVO usageEvent = new UsageEventVO( - EventTypes.EVENT_TEMPLATE_CREATE, - privateTemplate.getAccountId(), - zoneId, - privateTemplate.getId(), privateTemplate.getName(), - null, privateTemplate.getSourceTemplateId(), - privateTemplate.getSize()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_TEMPLATE_CREATE, privateTemplate.getAccountId(), zoneId, + privateTemplate.getId(), privateTemplate.getName(), null, privateTemplate.getSourceTemplateId(), privateTemplate.getSize()); _usageEventDao.persist(usageEvent); } catch (InterruptedException e) { s_logger.debug("Failed to create template", e); @@ -1430,8 +1487,11 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (privateTemplate == null) { Transaction txn = Transaction.currentTxn(); txn.start(); - // template_store_ref entries should have been removed using our DataObject.processEvent command in case of failure, but clean it up here to avoid - // some leftovers which will cause removing template from vm_template table fail. + // template_store_ref entries should have been removed using our + // DataObject.processEvent command in case of failure, but clean + // it up here to avoid + // some leftovers which will cause removing template from + // vm_template table fail. this._tmplStoreDao.deletePrimaryRecordsForTemplate(templateId); // Remove the template_zone_ref record this._tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId); @@ -1441,8 +1501,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // decrement resource count if (accountId != null) { _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template); - _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, - new Long(volume != null ? volume.getSize() : snapshot.getSize())); + _resourceLimitMgr.decrementResourceCount(accountId, ResourceType.secondary_storage, new Long(volume != null ? volume.getSize() + : snapshot.getSize())); } txn.commit(); } @@ -1456,14 +1516,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } private static boolean isAdmin(short accountType) { - return ((accountType == Account.ACCOUNT_TYPE_ADMIN) - || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) + return ((accountType == Account.ACCOUNT_TYPE_ADMIN) || (accountType == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) || (accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN)); } + @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_CREATE, eventDescription = "creating template", create = true) - public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, - Account templateOwner) throws ResourceAllocationException { + public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException { Long userId = UserContext.current().getCallerUserId(); Account caller = UserContext.current().getCaller(); @@ -1473,14 +1532,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, String name = cmd.getTemplateName(); if ((name == null) || (name.length() > 32)) { - throw new InvalidParameterValueException( - "Template name cannot be null and should be less than 32 characters"); + throw new InvalidParameterValueException("Template name cannot be null and should be less than 32 characters"); } if (cmd.getTemplateTag() != null) { if (!_accountService.isRootAdmin(caller.getType())) { - throw new PermissionDeniedException( - "Parameter templatetag can only be specified by a Root Admin, permission denied"); + throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied"); } } @@ -1491,33 +1548,26 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Boolean isPublic = cmd.isPublic(); Boolean featured = cmd.isFeatured(); int bitsValue = ((bits == null) ? 64 : bits.intValue()); - boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm - .booleanValue()); - boolean passwordEnabledValue = ((passwordEnabled == null) ? false - : passwordEnabled.booleanValue()); + boolean requiresHvmValue = ((requiresHvm == null) ? true : requiresHvm.booleanValue()); + boolean passwordEnabledValue = ((passwordEnabled == null) ? false : passwordEnabled.booleanValue()); if (isPublic == null) { isPublic = Boolean.FALSE; } // check whether template owner can create public templates - boolean allowPublicUserTemplates = Boolean.parseBoolean(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), Config.ConfigurationParameterScope.account.toString(), templateOwner.getId())); + boolean allowPublicUserTemplates = Boolean.parseBoolean(_configServer.getConfigValue(Config.AllowPublicUserTemplates.key(), + Config.ConfigurationParameterScope.account.toString(), templateOwner.getId())); if (!isAdmin && !allowPublicUserTemplates && isPublic) { - throw new PermissionDeniedException("Failed to create template " - + name + ", only private templates can be created."); + throw new PermissionDeniedException("Failed to create template " + name + ", only private templates can be created."); } Long volumeId = cmd.getVolumeId(); Long snapshotId = cmd.getSnapshotId(); if ((volumeId == null) && (snapshotId == null)) { - throw new InvalidParameterValueException( - "Failed to create private template record, neither volume ID nor snapshot ID were specified."); + throw new InvalidParameterValueException("Failed to create private template record, neither volume ID nor snapshot ID were specified."); } if ((volumeId != null) && (snapshotId != null)) { - throw new InvalidParameterValueException( - "Failed to create private template record, please specify only one of volume ID (" - + volumeId - + ") and snapshot ID (" - + snapshotId - + ")"); + throw new InvalidParameterValueException("Failed to create private template record, please specify only one of volume ID (" + volumeId + + ") and snapshot ID (" + snapshotId + ")"); } HypervisorType hyperType; @@ -1527,9 +1577,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (volumeId != null) { // create template from volume volume = this._volumeDao.findById(volumeId); if (volume == null) { - throw new InvalidParameterValueException( - "Failed to create private template record, unable to find volume " - + volumeId); + throw new InvalidParameterValueException("Failed to create private template record, unable to find volume " + volumeId); } // check permissions _accountMgr.checkAccess(caller, null, true, volume); @@ -1538,8 +1586,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // will not be active when the private template is // created if (!this._volumeMgr.volumeInactive(volume)) { - String msg = "Unable to create private template for volume: " - + volume.getName() + String msg = "Unable to create private template for volume: " + volume.getName() + "; volume is attached to a non-stopped VM, please stop the VM first"; if (s_logger.isInfoEnabled()) { s_logger.info(msg); @@ -1550,21 +1597,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } else { // create template from snapshot snapshot = _snapshotDao.findById(snapshotId); if (snapshot == null) { - throw new InvalidParameterValueException( - "Failed to create private template record, unable to find snapshot " - + snapshotId); + throw new InvalidParameterValueException("Failed to create private template record, unable to find snapshot " + snapshotId); } volume = this._volumeDao.findById(snapshot.getVolumeId()); - VolumeVO snapshotVolume = this._volumeDao - .findByIdIncludingRemoved(snapshot.getVolumeId()); + VolumeVO snapshotVolume = this._volumeDao.findByIdIncludingRemoved(snapshot.getVolumeId()); // check permissions _accountMgr.checkAccess(caller, null, true, snapshot); if (snapshot.getState() != Snapshot.State.BackedUp) { - throw new InvalidParameterValueException("Snapshot id=" - + snapshotId + " is not in " + Snapshot.State.BackedUp + throw new InvalidParameterValueException("Snapshot id=" + snapshotId + " is not in " + Snapshot.State.BackedUp + " state yet and can't be used for template creation"); } @@ -1590,30 +1633,25 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, Long guestOSId = cmd.getOsTypeId(); GuestOSVO guestOS = this._guestOSDao.findById(guestOSId); if (guestOS == null) { - throw new InvalidParameterValueException("GuestOS with ID: " - + guestOSId + " does not exist."); + throw new InvalidParameterValueException("GuestOS with ID: " + guestOSId + " does not exist."); } - String uniqueName = Long.valueOf((userId == null) ? 1 : userId) - .toString() - + UUID.nameUUIDFromBytes(name.getBytes()).toString(); + String uniqueName = Long.valueOf((userId == null) ? 1 : userId).toString() + UUID.nameUUIDFromBytes(name.getBytes()).toString(); Long nextTemplateId = this._tmpltDao.getNextInSequence(Long.class, "id"); String description = cmd.getDisplayText(); boolean isExtractable = false; Long sourceTemplateId = null; if (volume != null) { - VMTemplateVO template = ApiDBUtils.findTemplateById(volume - .getTemplateId()); - isExtractable = template != null - && template.isExtractable() - && template.getTemplateType() != Storage.TemplateType.SYSTEM; + VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); + isExtractable = template != null && template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; if (template != null) { sourceTemplateId = template.getId(); - } else if (volume.getVolumeType() == Volume.Type.ROOT) { // vm created out + } else if (volume.getVolumeType() == Volume.Type.ROOT) { // vm + // created + // out // of blank // template - UserVm userVm = ApiDBUtils.findUserVmById(volume - .getInstanceId()); + UserVm userVm = ApiDBUtils.findUserVmById(volume.getInstanceId()); sourceTemplateId = userVm.getIsoId(); } } @@ -1623,15 +1661,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, s_logger.debug("Adding template tag: " + templateTag); } } - privateTemplate = new VMTemplateVO(nextTemplateId, uniqueName, name, - ImageFormat.RAW, isPublic, featured, isExtractable, - TemplateType.USER, null, null, requiresHvmValue, bitsValue, - templateOwner.getId(), null, description, passwordEnabledValue, - guestOS.getId(), true, hyperType, templateTag, cmd.getDetails()); + privateTemplate = new VMTemplateVO(nextTemplateId, uniqueName, name, ImageFormat.RAW, isPublic, featured, isExtractable, TemplateType.USER, + null, null, requiresHvmValue, bitsValue, templateOwner.getId(), null, description, passwordEnabledValue, guestOS.getId(), true, + hyperType, templateTag, cmd.getDetails()); if (sourceTemplateId != null) { if (s_logger.isDebugEnabled()) { - s_logger.debug("This template is getting created from other template, setting source template Id to: " - + sourceTemplateId); + s_logger.debug("This template is getting created from other template, setting source template Id to: " + sourceTemplateId); } } privateTemplate.setSourceTemplateId(sourceTemplateId); @@ -1657,9 +1692,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, } @Override - public Pair getAbsoluteIsoPath(long templateId, - long dataCenterId) { - TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId, + public Pair getAbsoluteIsoPath(long templateId, long dataCenterId) { + TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, dataCenterId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); if (templateStoreRef == null) { throw new CloudRuntimeException("Template " + templateId + " has not been completely downloaded to zone " + dataCenterId); @@ -1679,19 +1713,19 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return secStore.getUri(); } - // get the image store where a template in a given zone is downloaded to, just pick one is enough. + // get the image store where a template in a given zone is downloaded to, + // just pick one is enough. @Override public DataStore getImageStore(long zoneId, long tmpltId) { - TemplateDataStoreVO tmpltStore = this._tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId, VMTemplateStorageResourceAssoc.Status.DOWNLOADED); - if (tmpltStore != null){ + TemplateDataStoreVO tmpltStore = this._tmplStoreDao.findByTemplateZoneDownloadStatus(tmpltId, zoneId, + VMTemplateStorageResourceAssoc.Status.DOWNLOADED); + if (tmpltStore != null) { return this._dataStoreMgr.getDataStore(tmpltStore.getDataStoreId(), DataStoreRole.Image); } return null; } - - @Override public Long getTemplateSize(long templateId, long zoneId) { TemplateDataStoreVO templateStoreRef = this._tmplStoreDao.findByTemplateZoneDownloadStatus(templateId, zoneId, @@ -1708,14 +1742,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, public List getImageStoreByTemplate(long templateId, Long zoneId) { // find all eligible image stores for this zone scope List imageStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId)); - if ( imageStores == null || imageStores.size() == 0 ){ + if (imageStores == null || imageStores.size() == 0) { return null; } List stores = new ArrayList(); - for (DataStore store : imageStores){ + for (DataStore store : imageStores) { // check if the template is stored there List storeTmpl = this._tmplStoreDao.listByTemplateStore(templateId, store.getId()); - if ( storeTmpl != null && storeTmpl.size() > 0 ){ + if (storeTmpl != null && storeTmpl.size() > 0) { stores.add(store); } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index a28da884e57..cefaee597ff 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2770,24 +2770,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use vm.setDetails(details); if (vm.getIsoId() != null) { - TemplateInfo template = templateFactory.getTemplate(vm.getIsoId(), DataStoreRole.Image, vm.getDataCenterId()); - - if (template == null || template.getFormat() != ImageFormat.ISO) { - throw new CloudRuntimeException( - "Can not find ISO in vm_template table for id " - + vm.getIsoId()); + TemplateInfo template = this.templateMgr.prepareIso(vm.getIsoId(), vm.getDataCenterId()); + if (template == null){ + s_logger.error("Failed to prepare ISO on secondary or cache storage"); + throw new CloudRuntimeException("Failed to prepare ISO on secondary or cache storage"); } - if (template.isBootable()) { profile.setBootLoaderType(BootloaderType.CD); } - + GuestOSVO guestOS = _guestOSDao.findById(template.getGuestOSId()); String displayName = null; if (guestOS != null) { displayName = guestOS.getDisplayName(); } - + TemplateObjectTO iso = (TemplateObjectTO)template.getTO(); iso.setGuestOsType(displayName); DiskTO disk = new DiskTO(iso, 3L, Volume.Type.ISO); From 2616115ff94176e55476a6379d8021aacdbbded9 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 29 May 2013 17:27:24 -0700 Subject: [PATCH 266/303] Still add system vm template to template_store_ref in adding image store, otherwise systemvm cannot come up. --- server/src/com/cloud/storage/StorageManagerImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index bb613b642f1..35fa3235717 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -1751,13 +1751,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C // trigger system vm template download this._imageSrv.downloadBootstrapSysTemplate(store); } - // for NFS, template store association will be populated in template sync phase - /* else { // populate template_store_ref table this._imageSrv.addSystemVMTemplatesToSecondary(store); } - */ // associate builtin template with zones associated with this image // store From 0a5228922b822b57af72249912ed854281e1d85a Mon Sep 17 00:00:00 2001 From: Edison Su Date: Wed, 29 May 2013 18:04:08 -0700 Subject: [PATCH 267/303] clean up storage related coded --- .../subsystem/api/storage/ClusterScope.java | 9 +- .../api/storage/CopyCommandResult.java | 7 +- .../api/storage/CreateCmdResult.java | 3 +- .../api/storage/DataMigrationSubSystem.java | 1 + .../api/storage/DataMotionService.java | 8 +- .../api/storage/DataMotionStrategy.java | 5 +- .../subsystem/api/storage/DataObject.java | 10 +- .../api/storage/DataObjectInStore.java | 5 +- .../subsystem/api/storage/DataStore.java | 9 + .../api/storage/DataStoreDriver.java | 9 + .../api/storage/DataStoreLifeCycle.java | 3 +- .../api/storage/DataStoreManager.java | 9 +- .../api/storage/DataStoreProvider.java | 14 +- .../api/storage/DataStoreProviderManager.java | 4 + .../subsystem/api/storage/EndPoint.java | 8 +- .../api/storage/EndPointSelector.java | 1 - .../subsystem/api/storage/HostScope.java | 5 +- .../api/storage/HypervisorHostListener.java | 1 + .../api/storage/ImageStoreProvider.java | 1 - .../ObjectInDataStoreStateMachine.java | 29 +- .../api/storage/PrimaryDataStoreDriver.java | 1 + .../api/storage/PrimaryDataStoreInfo.java | 16 +- .../storage/PrimaryDataStoreLifeCycle.java | 1 - .../storage/PrimaryDataStoreParameters.java | 40 +- .../engine/subsystem/api/storage/Scope.java | 2 + .../api/storage/SnapshotDataFactory.java | 3 +- .../subsystem/api/storage/SnapshotInfo.java | 17 +- .../api/storage/SnapshotProfile.java | 9 +- .../subsystem/api/storage/SnapshotResult.java | 43 +- .../api/storage/SnapshotService.java | 13 +- .../api/storage/SnapshotStrategy.java | 11 +- .../api/storage/StorageCacheManager.java | 8 +- .../subsystem/api/storage/StorageEvent.java | 4 +- .../api/storage/StorageOrchestrator.java | 18 +- .../api/storage/StoragePoolAllocator.java | 32 +- .../api/storage/StorageSubSystem.java | 2 + .../api/storage/TemplateDataFactory.java | 4 +- .../subsystem/api/storage/TemplateEvent.java | 5 +- .../subsystem/api/storage/TemplateInfo.java | 1 + .../api/storage/TemplateProfile.java | 489 +++--- .../api/storage/TemplateService.java | 21 +- .../subsystem/api/storage/TemplateState.java | 6 +- .../api/storage/VolumeDataFactory.java | 3 +- .../subsystem/api/storage/VolumeInfo.java | 17 +- .../subsystem/api/storage/VolumeProfile.java | 25 +- .../subsystem/api/storage/VolumeService.java | 23 +- .../subsystem/api/storage/ZoneScope.java | 5 +- .../api/storage/disktype/DiskFormat.java | 5 +- .../subsystem/api/storage/type/BaseImage.java | 6 +- .../subsystem/api/storage/type/DataDisk.java | 6 +- .../subsystem/api/storage/type/Iso.java | 6 +- .../subsystem/api/storage/type/RootDisk.java | 6 +- .../subsystem/api/storage/type/Unknown.java | 6 +- .../api/storage/type/VolumeTypeBase.java | 54 +- .../api/storage/type/VolumeTypeHelper.java | 34 +- .../storage/command/AttachAnswer.java | 2 + .../storage/command/AttachCommand.java | 13 +- .../command/AttachPrimaryDataStoreAnswer.java | 13 +- .../command/AttachPrimaryDataStoreCmd.java | 8 +- .../storage/command/CommandResult.java | 12 +- .../storage/command/CopyCmdAnswer.java | 8 +- .../storage/command/CopyCommand.java | 7 +- .../storage/command/CreateObjectAnswer.java | 10 +- .../storage/command/CreateObjectCommand.java | 5 +- .../command/CreatePrimaryDataStoreCmd.java | 10 +- .../storage/command/DeleteCommand.java | 15 +- .../storage/command/DettachAnswer.java | 4 +- .../storage/command/DettachCommand.java | 11 +- .../DownloadSystemTemplateCommand.java | 98 +- .../storage/datastore/db/ImageStoreDao.java | 6 +- .../datastore/db/ImageStoreDetailVO.java | 13 +- .../datastore/db/ImageStoreDetailsDao.java | 1 - .../storage/datastore/db/ImageStoreVO.java | 6 +- .../datastore/db/PrimaryDataStoreDao.java | 103 +- .../datastore/db/PrimaryDataStoreDaoImpl.java | 554 ++++--- .../db/PrimaryDataStoreDetailVO.java | 22 +- .../db/PrimaryDataStoreDetailsDao.java | 3 +- .../datastore/db/SnapshotDataStoreDao.java | 5 +- .../datastore/db/SnapshotDataStoreVO.java | 194 +-- .../datastore/db/StoragePoolDetailVO.java | 22 +- .../datastore/db/StoragePoolDetailsDao.java | 5 +- .../storage/datastore/db/StoragePoolVO.java | 24 +- .../datastore/db/TemplateDataStoreDao.java | 14 +- .../datastore/db/TemplateDataStoreVO.java | 224 ++- .../datastore/db/VolumeDataStoreDao.java | 5 +- .../datastore/db/VolumeDataStoreVO.java | 307 ++-- .../image/datastore/ImageStoreEntity.java | 5 + .../image/datastore/ImageStoreInfo.java | 1 + .../cloudstack/storage/to/ImageStoreTO.java | 3 +- .../storage/to/NfsPrimaryDataStoreTO.java | 44 - .../storage/to/PrimaryDataStoreTO.java | 12 +- .../storage/to/SnapshotObjectTO.java | 84 +- .../storage/to/TemplateObjectTO.java | 60 +- .../cloudstack/storage/to/VolumeObjectTO.java | 39 +- .../src/com/cloud/storage/DiskOfferingVO.java | 112 +- .../com/cloud/storage/GuestOSCategoryVO.java | 23 +- .../src/com/cloud/storage/GuestOSVO.java | 35 +- .../com/cloud/storage/LaunchPermissionVO.java | 11 +- engine/schema/src/com/cloud/storage/S3VO.java | 23 +- .../com/cloud/storage/SnapshotPolicyVO.java | 40 +- .../com/cloud/storage/SnapshotScheduleVO.java | 80 +- .../src/com/cloud/storage/SnapshotVO.java | 59 +- .../cloud/storage/StoragePoolHostAssoc.java | 16 +- .../com/cloud/storage/StoragePoolHostVO.java | 94 +- .../com/cloud/storage/StoragePoolWorkVO.java | 38 +- .../schema/src/com/cloud/storage/SwiftVO.java | 33 +- .../src/com/cloud/storage/UploadVO.java | 272 ++- .../com/cloud/storage/VMTemplateDetailVO.java | 81 +- .../com/cloud/storage/VMTemplateHostVO.java | 310 ++-- .../src/com/cloud/storage/VMTemplateS3VO.java | 34 +- .../storage/VMTemplateStoragePoolVO.java | 298 ++-- .../com/cloud/storage/VMTemplateSwiftVO.java | 3 +- .../src/com/cloud/storage/VMTemplateVO.java | 234 +-- .../com/cloud/storage/VMTemplateZoneVO.java | 128 +- .../src/com/cloud/storage/VolumeHostVO.java | 320 ++-- .../src/com/cloud/storage/VolumeVO.java | 97 +- .../cloud/storage/dao/DiskOfferingDao.java | 8 +- .../storage/dao/DiskOfferingDaoImpl.java | 57 +- .../cloud/storage/dao/GuestOSCategoryDao.java | 2 +- .../storage/dao/GuestOSCategoryDaoImpl.java | 10 +- .../src/com/cloud/storage/dao/GuestOSDao.java | 2 +- .../com/cloud/storage/dao/GuestOSDaoImpl.java | 18 +- .../storage/dao/LaunchPermissionDao.java | 28 +- .../storage/dao/LaunchPermissionDaoImpl.java | 31 +- .../src/com/cloud/storage/dao/S3DaoImpl.java | 3 +- .../com/cloud/storage/dao/SnapshotDao.java | 28 +- .../cloud/storage/dao/SnapshotDaoImpl.java | 83 +- .../cloud/storage/dao/SnapshotPolicyDao.java | 12 +- .../storage/dao/SnapshotPolicyDaoImpl.java | 45 +- .../storage/dao/SnapshotScheduleDao.java | 5 +- .../storage/dao/SnapshotScheduleDaoImpl.java | 87 +- .../dao/StoragePoolDetailsDaoImpl.java | 35 +- .../storage/dao/StoragePoolHostDaoImpl.java | 18 +- .../cloud/storage/dao/StoragePoolWorkDao.java | 3 +- .../storage/dao/StoragePoolWorkDaoImpl.java | 62 +- .../com/cloud/storage/dao/SwiftDaoImpl.java | 2 +- .../src/com/cloud/storage/dao/UploadDao.java | 11 +- .../com/cloud/storage/dao/UploadDaoImpl.java | 111 +- .../com/cloud/storage/dao/VMTemplateDao.java | 45 +- .../cloud/storage/dao/VMTemplateDaoImpl.java | 1460 ++++++++--------- .../storage/dao/VMTemplateDetailsDao.java | 10 +- .../storage/dao/VMTemplateDetailsDaoImpl.java | 64 +- .../cloud/storage/dao/VMTemplateHostDao.java | 15 +- .../storage/dao/VMTemplateHostDaoImpl.java | 562 +++---- .../cloud/storage/dao/VMTemplatePoolDao.java | 36 +- .../storage/dao/VMTemplatePoolDaoImpl.java | 427 ++--- .../storage/dao/VMTemplateS3DaoImpl.java | 25 +- .../cloud/storage/dao/VMTemplateZoneDao.java | 6 +- .../storage/dao/VMTemplateZoneDaoImpl.java | 87 +- .../src/com/cloud/storage/dao/VolumeDao.java | 9 +- .../com/cloud/storage/dao/VolumeDaoImpl.java | 358 ++-- .../com/cloud/storage/dao/VolumeHostDao.java | 13 +- .../cloud/storage/dao/VolumeHostDaoImpl.java | 37 +- .../StorageCacheRandomAllocator.java | 11 +- .../manager/StorageCacheManagerImpl.java | 75 +- .../motion/AncientDataMotionStrategy.java | 183 +-- .../storage/motion/DataMotionServiceImpl.java | 16 +- .../image/TemplateDataFactoryImpl.java | 17 +- .../storage/image/TemplateServiceImpl.java | 168 +- .../image/manager/ImageDataManagerImpl.java | 6 +- .../ImageStoreProviderManagerImpl.java | 15 +- .../storage/image/store/ImageStoreImpl.java | 46 +- .../storage/image/store/TemplateObject.java | 169 +- .../MockLocalNfsSecondaryStorageResource.java | 66 +- .../allocator/StorageAllocatorTest.java | 705 ++++---- .../StorageAllocatorTestConfiguration.java | 47 +- .../cloudstack/storage/test/AopTest.java | 2 +- .../storage/test/AopTestAdvice.java | 20 +- .../storage/test/ChildTestConfiguration.java | 157 +- .../storage/test/CloudStackTestNGBase.java | 50 +- .../test/DirectAgentManagerSimpleImpl.java | 75 +- .../storage/test/DirectAgentTest.java | 38 +- ...stEndpointRpcServerDirectCallResource.java | 70 - .../MockHypervisorHostEndPointRpcServer.java | 72 - .../storage/test/MockLocalHostEndPoint.java | 17 +- .../storage/test/MockRpcCallBack.java | 12 +- .../test/MockStorageMotionStrategy.java | 4 +- .../storage/test/S3TemplateTest.java | 161 +- .../cloudstack/storage/test/SnapshotTest.java | 135 +- .../storage/test/StorageFactoryBean.java | 11 +- .../cloudstack/storage/test/StorageTest.java | 11 +- .../cloudstack/storage/test/TemplateTest.java | 148 +- .../cloudstack/storage/test/TestHttp.java | 17 +- .../cloudstack/storage/test/TestNG.java | 5 +- .../cloudstack/storage/test/TestNGAop.java | 6 +- .../cloudstack/storage/test/VolumeTest.java | 106 +- .../storage/test/VolumeTestVmware.java | 107 +- .../storage/test/volumeServiceTest.java | 540 +++--- .../snapshot/SnapshotDataFactoryImpl.java | 12 +- .../storage/snapshot/SnapshotObject.java | 10 +- .../storage/snapshot/SnapshotServiceImpl.java | 650 ++++---- .../snapshot/SnapshotStateMachineManager.java | 2 +- .../SnapshotStateMachineManagerImpl.java | 53 +- .../snapshot/SnapshotStrategyBase.java | 20 +- .../snapshot/XenserverSnapshotStrategy.java | 270 ++- .../storage/snapshot/db/SnapshotVO.java | 78 +- .../test/src/SnapshotDataFactoryTest.java | 23 +- .../apache/cloudstack/storage/BaseType.java | 1 + .../storage/HostEndpointRpcServer.java | 29 - .../HypervisorHostEndPointRpcServer.java | 119 -- .../cloudstack/storage/LocalHostEndpoint.java | 111 +- .../storage/RemoteHostEndPoint.java | 46 +- .../AbstractStoragePoolAllocator.java | 173 +- .../ClusterScopeStoragePoolAllocator.java | 45 +- ...GarbageCollectingStoragePoolAllocator.java | 17 +- .../allocator/LocalStoragePoolAllocator.java | 32 +- .../allocator/UseLocalForRootAllocator.java | 10 +- .../ZoneWideStoragePoolAllocator.java | 65 +- .../backup/SnapshotOnBackupStoreInfo.java | 5 +- .../backup/datastore/BackupStoreInfo.java | 5 +- .../storage/datastore/DataObjectManager.java | 9 +- .../datastore/DataObjectManagerImpl.java | 170 +- .../datastore/DataStoreManagerImpl.java | 14 +- .../datastore/ObjectInDataStoreManager.java | 11 +- .../ObjectInDataStoreManagerImpl.java | 146 +- .../storage/datastore/PrimaryDataStore.java | 3 +- .../datastore/PrimaryDataStoreEntityImpl.java | 20 +- .../PrimaryDataStoreProviderManager.java | 3 +- .../datastore/protocol/DataStoreProtocol.java | 8 +- .../DataStoreProviderManagerImpl.java | 24 +- .../storage/db/ObjectInDataStoreDao.java | 3 +- .../storage/db/ObjectInDataStoreDaoImpl.java | 29 +- .../storage/db/ObjectInDataStoreVO.java | 24 +- .../endpoint/DefaultEndPointSelector.java | 62 +- .../storage/image/TemplateEntityImpl.java | 5 +- .../image/datastore/ImageStoreHelper.java | 45 +- .../datastore/ImageStoreProviderManager.java | 6 + .../storage/image/db/ImageStoreDaoImpl.java | 10 +- .../image/db/ImageStoreDetailsDaoImpl.java | 20 +- .../image/db/SnapshotDataStoreDaoImpl.java | 26 +- .../image/db/TemplateDataStoreDaoImpl.java | 93 +- .../image/db/VolumeDataStoreDaoImpl.java | 30 +- .../image/motion/ImageMotionService.java | 6 +- .../storage/snapshot/SnapshotEntityImpl.java | 254 +-- .../datastore/PrimaryDataStoreHelper.java | 58 +- .../db/PrimaryDataStoreDetailsDaoImpl.java | 42 +- .../db/TemplatePrimaryDataStoreDao.java | 4 +- .../db/TemplatePrimaryDataStoreDaoImpl.java | 43 +- .../volume/db/TemplatePrimaryDataStoreVO.java | 18 +- .../datastore/PrimaryDataStoreImpl.java | 38 +- .../PrimaryDataStoreProviderManagerImpl.java | 6 +- .../provider/DefaultHostListener.java | 32 +- .../volume/TemplateInstallStrategy.java | 28 - .../volume/TemplateInstallStrategyImpl.java | 289 ---- .../storage/volume/VolumeDataFactoryImpl.java | 7 +- .../storage/volume/VolumeEntityImpl.java | 71 +- .../storage/volume/VolumeMotionService.java | 23 - .../storage/volume/VolumeObject.java | 81 +- .../storage/volume/VolumeServiceImpl.java | 617 ++++--- .../storage/volume/test/ConfiguratorTest.java | 64 +- .../storage/volume/test/Server.java | 17 +- .../volume/test/TestConfiguration.java | 2 +- .../volume/test/TestInProcessAsync.java | 7 +- .../allocator/RandomStoragePoolAllocator.java | 51 +- .../CloudStackImageStoreDriverImpl.java | 237 ++- .../CloudStackImageStoreLifeCycleImpl.java | 70 +- .../CloudStackImageStoreProviderImpl.java | 7 +- .../driver/S3ImageStoreDriverImpl.java | 140 +- .../lifecycle/S3ImageStoreLifeCycleImpl.java | 69 +- .../provider/S3ImageStoreProviderImpl.java | 10 +- .../driver/SampleImageStoreDriverImpl.java | 29 +- .../SampleImageStoreLifeCycleImpl.java | 25 +- .../SampleImageStoreProviderImpl.java | 6 +- .../driver/SwiftImageStoreDriverImpl.java | 126 +- .../SwiftImageStoreLifeCycleImpl.java | 52 +- .../provider/SwiftImageStoreProviderImpl.java | 7 +- .../CloudStackPrimaryDataStoreDriverImpl.java | 313 ++-- ...oudStackPrimaryDataStoreLifeCycleImpl.java | 157 +- ...loudStackPrimaryDataStoreProviderImpl.java | 5 +- .../SamplePrimaryDataStoreDriverImpl.java | 184 +-- .../SamplePrimaryDataStoreLifeCycleImpl.java | 24 +- .../SamplePrimaryDatastoreProviderImpl.java | 6 +- .../SolidfirePrimaryDataStoreDriver.java | 20 +- .../SolidfirePrimaryDataStoreProvider.java | 19 +- .../storage/test/AopTestAdvice.java | 20 +- .../storage/test/ChildTestConfiguration.java | 47 +- .../storage/test/TestConfiguration.java | 17 +- .../cloudstack/storage/test/VolumeTest.java | 157 +- 278 files changed, 8757 insertions(+), 9784 deletions(-) delete mode 100644 engine/api/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java delete mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java delete mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervisorHostEndPointRpcServer.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java delete mode 100644 engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java delete mode 100644 engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java delete mode 100644 engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java delete mode 100644 engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java index 938f055b2d9..15e6d45f9ca 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java @@ -20,19 +20,18 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.ScopeType; - public class ClusterScope extends AbstractScope { private ScopeType type = ScopeType.CLUSTER; private Long clusterId; private Long podId; private Long zoneId; - + public ClusterScope(Long clusterId, Long podId, Long zoneId) { this.clusterId = clusterId; this.podId = podId; this.zoneId = zoneId; } - + @Override public ScopeType getScopeType() { return this.type; @@ -42,11 +41,11 @@ public class ClusterScope extends AbstractScope { public Long getScopeId() { return this.clusterId; } - + public Long getPodId() { return this.podId; } - + public Long getZoneId() { return this.zoneId; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java index e9d7b110341..bb5ba14d25d 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CopyCommandResult.java @@ -25,17 +25,18 @@ import com.cloud.agent.api.Answer; public class CopyCommandResult extends CommandResult { private final String path; private final Answer answer; + public CopyCommandResult(String path, Answer answer) { super(); this.path = path; this.answer = answer; } - + public String getPath() { return this.path; } - + public Answer getAnswer() { - return this.answer; + return this.answer; } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java index 2ecd97d071d..d05653cafb1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/CreateCmdResult.java @@ -25,12 +25,13 @@ import com.cloud.agent.api.Answer; public class CreateCmdResult extends CommandResult { private String path; private Answer answer; + public CreateCmdResult(String path, Answer answer) { super(); this.path = path; this.answer = answer; } - + public String getPath() { return this.path; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java index 65928bd5537..ad810432fd2 100755 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java @@ -25,5 +25,6 @@ import com.cloud.org.Grouping; public interface DataMigrationSubSystem { Class getScopeCoverage(); + void migrate(URI source, URI dest, String reservationId); } 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 index 40d6814e36b..5a124aa2725 100644 --- 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 @@ -18,7 +18,6 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; - import java.util.Map; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -27,10 +26,9 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; public interface DataMotionService { - public void copyAsync(DataObject srcData, DataObject destData, + public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); + + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback); - public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, - Host srcHost, Host destHost, AsyncCompletionCallback callback); - } 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 index d2d35b7c077..5bff21f3c8a 100644 --- 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 @@ -18,7 +18,6 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; - import java.util.Map; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -26,14 +25,12 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; - public interface DataMotionStrategy { public boolean canHandle(DataObject srcData, DataObject destData); public boolean canHandle(Map volumeMap, Host srcHost, Host destHost); - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback); + public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index 7610bca59bb..ef8798951c9 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -24,13 +24,21 @@ import com.cloud.agent.api.to.DataTO; public interface DataObject { public long getId(); + public String getUri(); + public DataTO getTO(); + public DataStore getDataStore(); + public Long getSize(); + public DataObjectType getType(); - //public DiskFormat getFormat(); + + // public DiskFormat getFormat(); public String getUuid(); + public void processEvent(ObjectInDataStoreStateMachine.Event event); + public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java index 0bfbd9a7aa4..929774c67c9 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java @@ -20,11 +20,14 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.utils.fsm.StateObject; - public interface DataObjectInStore extends StateObject { public String getInstallPath(); + public void setInstallPath(String path); + public long getObjectId(); + public long getDataStoreId(); + public ObjectInDataStoreStateMachine.State getObjectInStoreState(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java index c0570a9148d..e9a8f50e105 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStore.java @@ -21,13 +21,22 @@ import com.cloud.storage.DataStoreRole; public interface DataStore { DataStoreDriver getDriver(); + DataStoreRole getRole(); + long getId(); + String getUuid(); + String getUri(); + Scope getScope(); + String getName(); + DataObject create(DataObject obj); + boolean delete(DataObject obj); + DataStoreTO getTO(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java index 5ed9ab838ad..21430805c67 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java @@ -28,13 +28,22 @@ import com.cloud.agent.api.to.DataTO; public interface DataStoreDriver { public String grantAccess(DataObject data, EndPoint ep); + public boolean revokeAccess(DataObject data, EndPoint ep); + public Set listObjects(DataStore store); + public void createAsync(DataObject data, AsyncCompletionCallback callback); + public void deleteAsync(DataObject data, AsyncCompletionCallback callback); + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback); + public boolean canCopy(DataObject srcData, DataObject destData); + public void resize(DataObject data, AsyncCompletionCallback callback); + public DataTO getTO(DataObject data); + public DataStoreTO getStoreTO(DataStore store); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java index 2440bfdb197..d714df33df3 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java @@ -22,12 +22,13 @@ import java.util.Map; import com.cloud.agent.api.StoragePoolInfo; - public interface DataStoreLifeCycle { public DataStore initialize(Map dsInfos); public boolean attachCluster(DataStore store, ClusterScope scope); + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo); + boolean attachZone(DataStore dataStore, ZoneScope scope); public boolean dettach(); 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 e61734aded6..8617eb4c2ad 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 @@ -23,15 +23,22 @@ import java.util.Map; import com.cloud.storage.DataStoreRole; - public interface DataStoreManager { public DataStore getDataStore(long storeId, DataStoreRole role); + public DataStore getPrimaryDataStore(long storeId); + public DataStore getDataStore(String uuid, DataStoreRole role); + public List getImageStoresByScope(ZoneScope scope); + public DataStore getImageStore(long zoneId); + public List getImageStoresByProvider(String provider); + public List getImageCacheStores(Scope scope); + public DataStore registerDataStore(Map params, String providerUuid); + public List listImageStores(); } 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 cdcdef8a8b4..a13c60bd772 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 @@ -21,9 +21,6 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.Map; import java.util.Set; - - - public interface DataStoreProvider { // constants for provider names public static final String NFS_IMAGE = "NFS"; @@ -34,16 +31,19 @@ public interface DataStoreProvider { public static final String DEFAULT_PRIMARY = "DefaultPrimary"; public static enum DataStoreProviderType { - PRIMARY, - IMAGE, - ImageCache + PRIMARY, IMAGE, ImageCache } + public DataStoreLifeCycle getDataStoreLifeCycle(); + public DataStoreDriver getDataStoreDriver(); + public HypervisorHostListener getHostListener(); + public String getName(); + public boolean configure(Map params); + public Set getTypes(); - } 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 6872bdfc726..84272ef412c 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 @@ -25,9 +25,13 @@ import com.cloud.utils.component.Manager; public interface DataStoreProviderManager extends Manager, DataStoreProviderApiService { public DataStoreProvider getDataStoreProvider(String name); + public DataStoreProvider getDefaultPrimaryDataStoreProvider(); + public DataStoreProvider getDefaultImageDataStoreProvider(); + public DataStoreProvider getDefaultCacheDataStoreProvider(); + public List getDataStoreProviders(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java index 904ee989f2c..ed9c0ebe908 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java @@ -23,8 +23,12 @@ import com.cloud.agent.api.Command; public interface EndPoint { public long getId(); + public String getHostAddr(); + public String getPublicAddr(); - public Answer sendMessage(Command cmd); - public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); + + public Answer sendMessage(Command cmd); + + public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java index d3eb1ecd3f7..a51fad817c0 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java @@ -20,7 +20,6 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.List; - public interface EndPointSelector { public EndPoint select(DataObject srcData, DataObject destData); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java index ab21f6805e4..ff33077146a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java @@ -20,9 +20,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.ScopeType; - public class HostScope extends AbstractScope { - private ScopeType type = ScopeType.HOST; private Long hostId; private Long zoneId; @@ -30,9 +28,10 @@ public class HostScope extends AbstractScope { this.hostId = hostId; this.zoneId = zoneId; } + @Override public ScopeType getScopeType() { - return this.type; + return ScopeType.HOST; } @Override diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java index 3ac17598bb0..8db4101ffc0 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HypervisorHostListener.java @@ -20,5 +20,6 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface HypervisorHostListener { boolean hostConnect(long hostId, long poolId); + boolean hostDisconnected(long hostId, long poolId); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index 0f3f05b3ee7..bde4fe4c597 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java @@ -20,7 +20,6 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.ScopeType; - public interface ImageStoreProvider extends DataStoreProvider { public boolean isScopeSupported(ScopeType scope); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java index 94ae800ab8e..04522f628d5 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ObjectInDataStoreStateMachine.java @@ -22,16 +22,11 @@ import com.cloud.utils.fsm.StateObject; public interface ObjectInDataStoreStateMachine extends StateObject { enum State { - Allocated("The initial state"), - Creating2("This is only used with createOnlyRequested event"), - Creating("The object is being creating on data store"), - Created("The object is created"), - Ready("Template downloading is accomplished"), - Copying("The object is being coping"), - Migrating("The object is being migrated"), - Destroying("Template is destroying"), - Destroyed("Template is destroyed"), - Failed("Failed to download template"); + Allocated("The initial state"), Creating2("This is only used with createOnlyRequested event"), Creating( + "The object is being creating on data store"), Created("The object is created"), Ready( + "Template downloading is accomplished"), Copying("The object is being coping"), Migrating( + "The object is being migrated"), Destroying("Template is destroying"), Destroyed( + "Template is destroyed"), Failed("Failed to download template"); String _description; private State(String description) { @@ -42,17 +37,9 @@ public interface ObjectInDataStoreStateMachine extends StateObject callback); + public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java index 3497f7a894f..c69cd3a75cb 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java @@ -18,7 +18,6 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; - import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -26,12 +25,15 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; public interface PrimaryDataStoreInfo extends StoragePool { - public boolean isHypervisorSupported(HypervisorType hypervisor); - public boolean isLocalStorageSupported(); - public boolean isVolumeDiskTypeSupported(DiskFormat diskType); + public boolean isHypervisorSupported(HypervisorType hypervisor); - public String getUuid(); + public boolean isLocalStorageSupported(); - public StoragePoolType getPoolType(); - public PrimaryDataStoreLifeCycle getLifeCycle(); + public boolean isVolumeDiskTypeSupported(DiskFormat diskType); + + public String getUuid(); + + public StoragePoolType getPoolType(); + + public PrimaryDataStoreLifeCycle getLifeCycle(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java index cf29d9fea09..28b06f5234c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreLifeCycle.java @@ -18,6 +18,5 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; - public interface PrimaryDataStoreLifeCycle extends DataStoreLifeCycle { } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java index b2b787cc133..3b5362a2d06 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreParameters.java @@ -36,6 +36,7 @@ public class PrimaryDataStoreParameters { private String uuid; private String name; private String userInfo; + /** * @return the userInfo */ @@ -44,7 +45,8 @@ public class PrimaryDataStoreParameters { } /** - * @param userInfo the userInfo to set + * @param userInfo + * the userInfo to set */ public void setUserInfo(String userInfo) { this.userInfo = userInfo; @@ -58,7 +60,8 @@ public class PrimaryDataStoreParameters { } /** - * @param name the name to set + * @param name + * the name to set */ public void setName(String name) { this.name = name; @@ -72,7 +75,8 @@ public class PrimaryDataStoreParameters { } /** - * @param uuid the uuid to set + * @param uuid + * the uuid to set */ public void setUuid(String uuid) { this.uuid = uuid; @@ -86,7 +90,8 @@ public class PrimaryDataStoreParameters { } /** - * @param port the port to set + * @param port + * the port to set */ public void setPort(int port) { this.port = port; @@ -100,7 +105,8 @@ public class PrimaryDataStoreParameters { } /** - * @param path the path to set + * @param path + * the path to set */ public void setPath(String path) { this.path = path; @@ -114,7 +120,8 @@ public class PrimaryDataStoreParameters { } /** - * @param host the host to set + * @param host + * the host to set */ public void setHost(String host) { this.host = host; @@ -128,7 +135,8 @@ public class PrimaryDataStoreParameters { } /** - * @param type the type to set + * @param type + * the type to set */ public void setType(StoragePoolType type) { this.type = type; @@ -142,7 +150,8 @@ public class PrimaryDataStoreParameters { } /** - * @param tags the tags to set + * @param tags + * the tags to set */ public void setTags(String tags) { this.tags = tags; @@ -156,7 +165,8 @@ public class PrimaryDataStoreParameters { } /** - * @param details the details to set + * @param details + * the details to set */ public void setDetails(Map details) { this.details = details; @@ -170,7 +180,8 @@ public class PrimaryDataStoreParameters { } /** - * @param providerName the providerName to set + * @param providerName + * the providerName to set */ public void setProviderName(String providerName) { this.providerName = providerName; @@ -184,7 +195,8 @@ public class PrimaryDataStoreParameters { } /** - * @param clusterId the clusterId to set + * @param clusterId + * the clusterId to set */ public void setClusterId(Long clusterId) { this.clusterId = clusterId; @@ -198,7 +210,8 @@ public class PrimaryDataStoreParameters { } /** - * @param podId the podId to set + * @param podId + * the podId to set */ public void setPodId(Long podId) { this.podId = podId; @@ -212,7 +225,8 @@ public class PrimaryDataStoreParameters { } /** - * @param zoneId the zoneId to set + * @param zoneId + * the zoneId to set */ public void setZoneId(Long zoneId) { this.zoneId = zoneId; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java index 25226f984ea..5c71f3cc220 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java @@ -22,6 +22,8 @@ import com.cloud.storage.ScopeType; public interface Scope { public ScopeType getScopeType(); + public boolean isSameScope(Scope scope); + public Long getScopeId(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java index 0e9e3b3aec0..04b67d427c1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java @@ -20,9 +20,10 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.DataStoreRole; - public interface SnapshotDataFactory { public SnapshotInfo getSnapshot(long snapshotId, DataStore store); + public SnapshotInfo getSnapshot(DataObject obj, DataStore store); + public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java index 41ea5f3dd3c..91e0fd79fa9 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java @@ -18,13 +18,18 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.Snapshot; - public interface SnapshotInfo extends DataObject, Snapshot { - public SnapshotInfo getParent(); - public String getPath(); - public SnapshotInfo getChild(); - public VolumeInfo getBaseVolume(); - public void addPayload(Object data); + public SnapshotInfo getParent(); + + public String getPath(); + + public SnapshotInfo getChild(); + + public VolumeInfo getBaseVolume(); + + public void addPayload(Object data); + Long getDataCenterId(); + ObjectInDataStoreStateMachine.State getStatus(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java index 50a12002cf2..a51a51dedf8 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotProfile.java @@ -19,8 +19,9 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public class SnapshotProfile { - private String _uri; - public String getURI() { - return _uri; - } + private String _uri; + + public String getURI() { + return _uri; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java index a886a86b921..80dbbf83590 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotResult.java @@ -16,28 +16,33 @@ // under the License. package org.apache.cloudstack.engine.subsystem.api.storage; - import org.apache.cloudstack.storage.command.CommandResult; import com.cloud.agent.api.Answer; public class SnapshotResult extends CommandResult { - private SnapshotInfo snashot; - private Answer answer; - public SnapshotResult(SnapshotInfo snapshot, Answer answer) { - this.setSnashot(snapshot); - this.setAnswer(answer); - } - public SnapshotInfo getSnashot() { - return snashot; - } - public void setSnashot(SnapshotInfo snashot) { - this.snashot = snashot; - } - public Answer getAnswer() { - return answer; - } - public void setAnswer(Answer answer) { - this.answer = answer; - } + private SnapshotInfo snashot; + private Answer answer; + + public SnapshotResult(SnapshotInfo snapshot, Answer answer) { + super(); + this.setSnashot(snapshot); + this.setAnswer(answer); + } + + public SnapshotInfo getSnashot() { + return snashot; + } + + public void setSnashot(SnapshotInfo snashot) { + this.snashot = snashot; + } + + public Answer getAnswer() { + return answer; + } + + public void setAnswer(Answer answer) { + this.answer = answer; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java index b248054e569..67c88471dfc 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java @@ -17,11 +17,12 @@ package org.apache.cloudstack.engine.subsystem.api.storage; - - public interface SnapshotService { - public SnapshotResult takeSnapshot(SnapshotInfo snapshot); - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(SnapshotInfo snapshot); - public boolean revertSnapshot(SnapshotInfo snapshot); + public SnapshotResult takeSnapshot(SnapshotInfo snapshot); + + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); + + public boolean deleteSnapshot(SnapshotInfo snapshot); + + public boolean revertSnapshot(SnapshotInfo snapshot); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java index 2a0d2bb30cb..542246ae36f 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java @@ -18,12 +18,13 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.Snapshot; - - public interface SnapshotStrategy { - public SnapshotInfo takeSnapshot(SnapshotInfo snapshot); - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(Long snapshotId); + public SnapshotInfo takeSnapshot(SnapshotInfo snapshot); + + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); + + public boolean deleteSnapshot(Long snapshotId); + /** * @param snapshot * @return 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 index 917a5376526..fd5211f1dd0 100644 --- 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 @@ -18,15 +18,19 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; - public interface StorageCacheManager { public DataStore getCacheStorage(Scope scope); + public DataObject createCacheObject(DataObject data, Scope scope); - /** only create cache object in db + + /** + * only create cache object in db + * * @param data * @param scope * @return */ DataObject getCacheObject(DataObject data, Scope scope); + boolean deleteCacheObject(DataObject data); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java index 3f64002ed9e..6147b6ab6cc 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageEvent.java @@ -19,7 +19,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public enum StorageEvent { - DownloadTemplateToPrimary, - RegisterTemplate, - CreateVolumeFromTemplate; + DownloadTemplateToPrimary, RegisterTemplate, CreateVolumeFromTemplate; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java index fdb15c7331c..d4455c8059a 100755 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java @@ -31,6 +31,7 @@ public interface StorageOrchestrator { /** * Prepares all storage ready for a VM to start + * * @param vm * @param reservationId */ @@ -38,6 +39,7 @@ public interface StorageOrchestrator { /** * Releases all storage that were used for a VM shutdown + * * @param vm * @param disks * @param reservationId @@ -46,6 +48,7 @@ public interface StorageOrchestrator { /** * Destroy all disks + * * @param disks * @param reservationId */ @@ -53,16 +56,21 @@ public interface StorageOrchestrator { /** * Cancel a reservation - * @param reservationId reservation to + * + * @param reservationId + * reservation to */ void cancel(String reservationId); - + /** - * If attaching a volume in allocated state to a running vm, need to create this volume + * If attaching a volume in allocated state to a running vm, need to create + * this volume */ void prepareAttachDiskToVM(long diskId, long vmId, String reservationId); - + boolean createVolume(VolumeEntity volume, long dataStoreId, DiskFormat diskType); + boolean createVolumeFromTemplate(VolumeEntity volume, long dataStoreId, DiskFormat dis, TemplateEntity template); - VolumeEntity allocateVolumeInDb(long size, VolumeType type,String volName, Long templateId); + + VolumeEntity allocateVolumeInDb(long size, VolumeType type, String volName, Long templateId); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java index ffced54c28c..13eb0de6f70 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java @@ -29,17 +29,23 @@ import com.cloud.vm.VirtualMachineProfile; /** */ public interface StoragePoolAllocator extends Adapter { - /** - * Determines which storage pools are suitable for the guest virtual machine - * - * @param DiskProfile dskCh - * @param VirtualMachineProfile vmProfile - * @param DeploymentPlan plan - * @param ExcludeList avoid - * @param int returnUpTo (use -1 to return all possible pools) - * @return List List of storage pools that are suitable for the VM - **/ - List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); - - public static int RETURN_UPTO_ALL = -1; + /** + * Determines which storage pools are suitable for the guest virtual machine + * + * @param DiskProfile + * dskCh + * @param VirtualMachineProfile + * vmProfile + * @param DeploymentPlan + * plan + * @param ExcludeList + * avoid + * @param int returnUpTo (use -1 to return all possible pools) + * @return List List of storage pools that are suitable for the + * VM + **/ + List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo); + + public static int RETURN_UPTO_ALL = -1; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java index 8043487d46b..e5a74a452a1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java @@ -22,8 +22,10 @@ import com.cloud.org.Grouping; public interface StorageSubSystem { String getType(); + Class getScope(); URI grantAccess(String vol, String reservationId); + URI RemoveAccess(String vol, String reservationId); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java index 8916f6681cf..0b78da058ed 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateDataFactory.java @@ -20,10 +20,12 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.DataStoreRole; - public interface TemplateDataFactory { TemplateInfo getTemplate(long templateId, DataStore store); + TemplateInfo getTemplate(DataObject obj, DataStore store); + TemplateInfo getTemplate(long templateId, DataStoreRole storeRole); + TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java index c677166b39a..be74c7a9d8a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateEvent.java @@ -19,8 +19,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public enum TemplateEvent { - CreateRequested, - OperationFailed, - OperationSucceeded, - DestroyRequested; + CreateRequested, OperationFailed, OperationSucceeded, DestroyRequested; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java index 3ee1d2faf01..91dba115e09 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java @@ -22,5 +22,6 @@ import com.cloud.template.VirtualMachineTemplate; public interface TemplateInfo extends DataObject, VirtualMachineTemplate { public String getUniqueName(); + public String getInstallPath(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java index e05e7db67fa..dcfd4074bfd 100755 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java @@ -22,266 +22,291 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Storage.ImageFormat; import com.cloud.template.VirtualMachineTemplate; -public class TemplateProfile { - Long userId; - String name; - String displayText; - Integer bits; - Boolean passwordEnabled; - Boolean sshKeyEnbaled; - Boolean requiresHvm; - String url; - Boolean isPublic; - Boolean featured; - Boolean isExtractable; - ImageFormat format; - Long guestOsId; - Long zoneId; - HypervisorType hypervisorType; - String accountName; - Long domainId; - Long accountId; - String chksum; - Boolean bootable; - Long templateId; - VirtualMachineTemplate template; - String templateTag; - Map details; - - public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, - String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, - HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details, Boolean sshKeyEnabled) { - this.templateId = templateId; - this.userId = userId; - this.name = name; - this.displayText = displayText; - this.bits = bits; - this.passwordEnabled = passwordEnabled; - this.requiresHvm = requiresHvm; - this.url = url; - this.isPublic = isPublic; - this.featured = featured; - this.isExtractable = isExtractable; - this.format = format; - this.guestOsId = guestOsId; - this.zoneId = zoneId; - this.hypervisorType = hypervisorType; - this.accountName = accountName; - this.domainId = domainId; - this.accountId = accountId; - this.chksum = chksum; - this.bootable = bootable; - this.details = details; - this.sshKeyEnbaled = sshKeyEnabled; - } - - public TemplateProfile(Long userId, VirtualMachineTemplate template, Long zoneId) { - this.userId = userId; - this.template = template; - this.zoneId = zoneId; - } - - public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, Boolean passwordEnabled, Boolean requiresHvm, - String url, Boolean isPublic, Boolean featured, Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, - HypervisorType hypervisorType, String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, Map details, Boolean sshKeyEnabled) { - this(templateId, userId, name, displayText, bits, passwordEnabled, requiresHvm, url, isPublic, featured, isExtractable, format, guestOsId, zoneId, - hypervisorType, accountName, domainId, accountId, chksum, bootable, details, sshKeyEnabled); +public class TemplateProfile { + Long userId; + String name; + String displayText; + Integer bits; + Boolean passwordEnabled; + Boolean sshKeyEnbaled; + Boolean requiresHvm; + String url; + Boolean isPublic; + Boolean featured; + Boolean isExtractable; + ImageFormat format; + Long guestOsId; + Long zoneId; + HypervisorType hypervisorType; + String accountName; + Long domainId; + Long accountId; + String chksum; + Boolean bootable; + Long templateId; + VirtualMachineTemplate template; + String templateTag; + Map details; + + public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, + Boolean passwordEnabled, Boolean requiresHvm, String url, Boolean isPublic, Boolean featured, + Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, HypervisorType hypervisorType, + String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details, + Boolean sshKeyEnabled) { + this.templateId = templateId; + this.userId = userId; + this.name = name; + this.displayText = displayText; + this.bits = bits; + this.passwordEnabled = passwordEnabled; + this.requiresHvm = requiresHvm; + this.url = url; + this.isPublic = isPublic; + this.featured = featured; + this.isExtractable = isExtractable; + this.format = format; + this.guestOsId = guestOsId; + this.zoneId = zoneId; + this.hypervisorType = hypervisorType; + this.accountName = accountName; + this.domainId = domainId; + this.accountId = accountId; + this.chksum = chksum; + this.bootable = bootable; + this.details = details; + this.sshKeyEnbaled = sshKeyEnabled; + } + + public TemplateProfile(Long userId, VirtualMachineTemplate template, Long zoneId) { + this.userId = userId; + this.template = template; + this.zoneId = zoneId; + } + + public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, + Boolean passwordEnabled, Boolean requiresHvm, String url, Boolean isPublic, Boolean featured, + Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, HypervisorType hypervisorType, + String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, + Map details, Boolean sshKeyEnabled) { + this(templateId, userId, name, displayText, bits, passwordEnabled, requiresHvm, url, isPublic, featured, + isExtractable, format, guestOsId, zoneId, hypervisorType, accountName, domainId, accountId, chksum, + bootable, details, sshKeyEnabled); this.templateTag = templateTag; - } - - public Long getTemplateId() { - return templateId; - } - public void setTemplateId(Long id) { - this.templateId = id; - } - - public Long getUserId() { - return userId; - } - public void setUserId(Long userId) { - this.userId = userId; - } - - public String getName() { - return name; - } - public void setName(String name) { - this.name = name; - } - - public String getDisplayText() { - return displayText; - } - public void setDisplayText(String text) { - this.displayText = text; - } - - public Integer getBits() { - return bits; - } - public void setBits(Integer bits) { - this.bits = bits; - } - - public Boolean getPasswordEnabled() { - return passwordEnabled; - } - public void setPasswordEnabled(Boolean enabled) { - this.passwordEnabled = enabled; - } - - public Boolean getRequiresHVM() { - return requiresHvm; - } - public void setRequiresHVM(Boolean hvm) { - this.requiresHvm = hvm; - } - - public String getUrl() { - return url; - } - public void setUrl(String url) { - this.url = url; - } - - public Boolean getIsPublic() { - return isPublic; - } - public void setIsPublic(Boolean is) { - this.isPublic = is; - } - - public Boolean getFeatured() { - return featured; - } - public void setFeatured(Boolean featured) { - this.featured = featured; - } - - public Boolean getIsExtractable() { - return isExtractable; - } - public void setIsExtractable(Boolean is) { - this.isExtractable = is; - } - - public ImageFormat getFormat() { - return format; - } - public void setFormat(ImageFormat format) { - this.format = format; - } - - public Long getGuestOsId() { - return guestOsId; - } - public void setGuestOsId(Long id) { - this.guestOsId = id; - } - - public Long getZoneId() { - return zoneId; - } - public void setZoneId(Long id) { - this.zoneId = id; - } - - public HypervisorType getHypervisorType() { - return hypervisorType; - } - public void setHypervisorType(HypervisorType type) { - this.hypervisorType = type; - } - - public Long getDomainId() { - return domainId; - } - public void setDomainId(Long id) { - this.domainId = id; - } - - public Long getAccountId() { - return accountId; - } - public void setAccountId(Long id) { - this.accountId = id; - } - - public String getCheckSum() { - return chksum; - } - public void setCheckSum(String chksum) { - this.chksum = chksum; - } - - public Boolean getBootable() { - return this.bootable; - } - public void setBootable(Boolean bootable) { - this.bootable = bootable; - } - - public VirtualMachineTemplate getTemplate() { - return template; - } - public void setTemplate(VirtualMachineTemplate template) { - this.template = template; - } - + } + + public Long getTemplateId() { + return templateId; + } + + public void setTemplateId(Long id) { + this.templateId = id; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDisplayText() { + return displayText; + } + + public void setDisplayText(String text) { + this.displayText = text; + } + + public Integer getBits() { + return bits; + } + + public void setBits(Integer bits) { + this.bits = bits; + } + + public Boolean getPasswordEnabled() { + return passwordEnabled; + } + + public void setPasswordEnabled(Boolean enabled) { + this.passwordEnabled = enabled; + } + + public Boolean getRequiresHVM() { + return requiresHvm; + } + + public void setRequiresHVM(Boolean hvm) { + this.requiresHvm = hvm; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Boolean getIsPublic() { + return isPublic; + } + + public void setIsPublic(Boolean is) { + this.isPublic = is; + } + + public Boolean getFeatured() { + return featured; + } + + public void setFeatured(Boolean featured) { + this.featured = featured; + } + + public Boolean getIsExtractable() { + return isExtractable; + } + + public void setIsExtractable(Boolean is) { + this.isExtractable = is; + } + + public ImageFormat getFormat() { + return format; + } + + public void setFormat(ImageFormat format) { + this.format = format; + } + + public Long getGuestOsId() { + return guestOsId; + } + + public void setGuestOsId(Long id) { + this.guestOsId = id; + } + + public Long getZoneId() { + return zoneId; + } + + public void setZoneId(Long id) { + this.zoneId = id; + } + + public HypervisorType getHypervisorType() { + return hypervisorType; + } + + public void setHypervisorType(HypervisorType type) { + this.hypervisorType = type; + } + + public Long getDomainId() { + return domainId; + } + + public void setDomainId(Long id) { + this.domainId = id; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long id) { + this.accountId = id; + } + + public String getCheckSum() { + return chksum; + } + + public void setCheckSum(String chksum) { + this.chksum = chksum; + } + + public Boolean getBootable() { + return this.bootable; + } + + public void setBootable(Boolean bootable) { + this.bootable = bootable; + } + + public VirtualMachineTemplate getTemplate() { + return template; + } + + public void setTemplate(VirtualMachineTemplate template) { + this.template = template; + } + public String getTemplateTag() { return templateTag; - } + } public void setTemplateTag(String templateTag) { this.templateTag = templateTag; - } - + } + public Map getDetails() { - return this.details; + return this.details; } - + public void setDetails(Map details) { - this.details = details; + this.details = details; } - + public void setSshKeyEnabled(Boolean enabled) { - this.sshKeyEnbaled = enabled; + this.sshKeyEnbaled = enabled; } - + public Boolean getSshKeyEnabled() { - return this.sshKeyEnbaled; + return this.sshKeyEnbaled; } - + public String getImageStorageUri() { - return null; + return null; } - + public void setLocalPath(String path) { - + } - + public String getLocalPath() { - return null; + return null; } - + public String getJobId() { - return null; + return null; } - + public void setTemplatePoolRefId(long id) { - + } - + public long getId() { - return 0; + return 0; } - + public long getTemplatePoolRefId() { - return 0; + return 0; } - + public long getSize() { - return 0; + return 0; } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index 5e0c9f278a1..52e18f195f1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -22,8 +22,6 @@ import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; - - import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.StoragePool; @@ -31,7 +29,9 @@ public interface TemplateService { public class TemplateApiResult extends CommandResult { private final TemplateInfo template; + public TemplateApiResult(TemplateInfo template) { + super(); this.template = template; } @@ -40,16 +40,25 @@ public interface TemplateService { } } - void createTemplateAsync(TemplateInfo template, DataStore store, AsyncCompletionCallback callback); - AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, DataStore store); - AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, DataStore store); + + AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, TemplateInfo template, + DataStore store); + + AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, + DataStore store); + AsyncCallFuture deleteTemplateAsync(TemplateInfo template); + AsyncCallFuture copyTemplate(TemplateInfo srcTemplate, DataStore destStore); - AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool ); + + AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool); void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId); + void handleTemplateSync(DataStore store); + void downloadBootstrapSysTemplate(DataStore store); + void addSystemVMTemplatesToSecondary(DataStore store); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java index ef2488080f8..43ea82a2688 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateState.java @@ -19,9 +19,5 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public enum TemplateState { - Allocated, - Creating, - Destroying, - Destroyed, - Ready; + Allocated, Creating, Destroying, Destroyed, Ready; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java index 1518fd2eb43..fc65a32c33e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeDataFactory.java @@ -18,9 +18,10 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; - public interface VolumeDataFactory { VolumeInfo getVolume(long volumeId, DataStore store); + VolumeInfo getVolume(DataObject volume, DataStore store); + VolumeInfo getVolume(long volumeId); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 7165f370bac..d0b9be99678 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -22,10 +22,15 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Volume; public interface VolumeInfo extends DataObject, Volume { - public boolean isAttachedVM(); - public void addPayload(Object data); - public Object getpayload(); - public HypervisorType getHypervisorType(); - public Long getLastPoolId(); - public String getAttachedVmName(); + public boolean isAttachedVM(); + + public void addPayload(Object data); + + public Object getpayload(); + + public HypervisorType getHypervisorType(); + + public Long getLastPoolId(); + + public String getAttachedVmName(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java index ed4d42187be..8701912f304 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java @@ -19,16 +19,17 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public class VolumeProfile { - private String _uri; - public String getURI() { - return _uri; - } - - public String getPath() { - return null; - } - - public long getSize() { - return 0; - } + private String _uri; + + public String getURI() { + return _uri; + } + + public String getPath() { + return null; + } + + public long getSize() { + return 0; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java index 3f725e1077c..39479523271 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.Map; + import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.command.CommandResult; @@ -31,7 +32,9 @@ public interface VolumeService { public class VolumeApiResult extends CommandResult { private final VolumeInfo volume; + public VolumeApiResult(VolumeInfo volume) { + super(); this.volume = volume; } @@ -42,16 +45,16 @@ public interface VolumeService { /** * Creates the volume based on the given criteria - * + * * @param cmd - * + * * @return the volume object */ AsyncCallFuture createVolumeAsync(VolumeInfo volume, DataStore store); /** * Delete volume - * + * * @param volumeId * @return * @throws ConcurrentOperationException @@ -66,15 +69,19 @@ public interface VolumeService { /** * */ - AsyncCallFuture createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot); - + AsyncCallFuture createVolumeFromSnapshot(VolumeInfo volume, DataStore store, SnapshotInfo snapshot); VolumeEntity getVolumeEntity(long volumeId); - AsyncCallFuture createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template); + AsyncCallFuture createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, + TemplateInfo template); + AsyncCallFuture copyVolume(VolumeInfo srcVolume, DataStore destStore); + AsyncCallFuture migrateVolume(VolumeInfo srcVolume, DataStore destStore); - AsyncCallFuture migrateVolumes(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost); + + AsyncCallFuture migrateVolumes(Map volumeMap, VirtualMachineTO vmTo, + Host srcHost, Host destHost); boolean destroyVolume(long volumeId) throws ConcurrentOperationException; @@ -84,6 +91,6 @@ public interface VolumeService { void handleVolumeSync(DataStore store); - SnapshotInfo takeSnapshot(VolumeInfo volume); + SnapshotInfo takeSnapshot(VolumeInfo volume); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java index a71a9c7ffb5..9ba1d10012a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java @@ -20,15 +20,14 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.ScopeType; - public class ZoneScope extends AbstractScope { private ScopeType type = ScopeType.ZONE; private Long zoneId; - + public ZoneScope(Long zoneId) { this.zoneId = zoneId; } - + @Override public ScopeType getScopeType() { return this.type; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java index e059fa90320..6be7a6bb49e 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/disktype/DiskFormat.java @@ -19,10 +19,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage.disktype; import com.cloud.utils.exception.CloudRuntimeException; public enum DiskFormat { - VMDK, - VHD, - ISO, - QCOW2; + VMDK, VHD, ISO, QCOW2; public static DiskFormat getFormat(String format) { if (VMDK.toString().equalsIgnoreCase(format)) { return VMDK; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java index 9991cedfa27..495d45c183c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/BaseImage.java @@ -17,7 +17,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage.type; public class BaseImage extends VolumeTypeBase { - public BaseImage() { - this.type = "BaseImage"; - } + public BaseImage() { + this.type = "BaseImage"; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java index 762233e940f..a533f55d31c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/DataDisk.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; @Component public class DataDisk extends VolumeTypeBase { - public DataDisk() { - this.type = "DataDisk"; - } + public DataDisk() { + this.type = "DataDisk"; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java index 43611b461b1..85c62725597 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Iso.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; @Component public class Iso extends VolumeTypeBase { - public Iso() { - this.type = "iso"; - } + public Iso() { + this.type = "iso"; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java index 723d59c66cf..e8f4ce5c128 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/RootDisk.java @@ -20,7 +20,7 @@ import org.springframework.stereotype.Component; @Component public class RootDisk extends VolumeTypeBase { - public RootDisk() { - this.type = "Root"; - } + public RootDisk() { + this.type = "Root"; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java index 6f8904a5af2..f264d21757f 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/Unknown.java @@ -17,8 +17,8 @@ package org.apache.cloudstack.engine.subsystem.api.storage.type; public class Unknown extends VolumeTypeBase { - public Unknown() { - this.type = "Unknown"; - } + public Unknown() { + this.type = "Unknown"; + } } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java index 6ffd9d7c9c8..cf466ea8144 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeBase.java @@ -17,31 +17,31 @@ package org.apache.cloudstack.engine.subsystem.api.storage.type; public class VolumeTypeBase implements VolumeType { - protected String type = "Unknown"; - - @Override - public boolean equals(Object that) { - if (this == that) { - return true; - } - if (that instanceof String) { - if (this.toString().equalsIgnoreCase((String)that)) { - return true; - } - } else if (that instanceof VolumeTypeBase) { - VolumeTypeBase th = (VolumeTypeBase)that; - if (this.toString().equalsIgnoreCase(th.toString())) { - return true; - } - } else { - return false; - } - return false; - } - - @Override - public String toString() { - return type; - } - + protected String type = "Unknown"; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that instanceof String) { + if (this.toString().equalsIgnoreCase((String) that)) { + return true; + } + } else if (that instanceof VolumeTypeBase) { + VolumeTypeBase th = (VolumeTypeBase) that; + if (this.toString().equalsIgnoreCase(th.toString())) { + return true; + } + } else { + return false; + } + return false; + } + + @Override + public String toString() { + return type; + } + } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java index f29dd08721f..6dc2cd48c3d 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/type/VolumeTypeHelper.java @@ -24,21 +24,21 @@ import org.springframework.stereotype.Component; @Component public class VolumeTypeHelper { - static private List types; - private static VolumeType defaultType = new Unknown(); - - @Inject - public void setTypes(List types) { - VolumeTypeHelper.types = types; - } - - public static VolumeType getType(String type) { - for (VolumeType ty : types) { - if (ty.equals(type)) { - return ty; - } - } - return VolumeTypeHelper.defaultType; - } - + static private List types; + private static VolumeType defaultType = new Unknown(); + + @Inject + public void setTypes(List types) { + VolumeTypeHelper.types = types; + } + + public static VolumeType getType(String type) { + for (VolumeType ty : types) { + if (ty.equals(type)) { + return ty; + } + } + return VolumeTypeHelper.defaultType; + } + } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java index 092ec63df44..5a26d4a3f13 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachAnswer.java @@ -23,6 +23,7 @@ import com.cloud.agent.api.to.DiskTO; public class AttachAnswer extends Answer { private DiskTO disk; + public AttachAnswer() { super(null); } @@ -31,6 +32,7 @@ public class AttachAnswer extends Answer { super(null); this.setDisk(disk); } + public AttachAnswer(String errMsg) { super(null, false, errMsg); } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java index fa205a55eb6..6b4e9f7ed00 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachCommand.java @@ -18,33 +18,36 @@ */ package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DiskTO; -public class AttachCommand extends Command implements StorageSubSystemCommand { +public final class AttachCommand extends Command implements StorageSubSystemCommand { private DiskTO disk; private String vmName; - + public AttachCommand(DiskTO disk, String vmName) { + super(); this.disk = disk; this.vmName = vmName; } - + @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } + public DiskTO getDisk() { return disk; } + public void setDisk(DiskTO disk) { this.disk = disk; } + public String getVmName() { return vmName; } + public void setVmName(String vmName) { this.vmName = vmName; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java index cd15030084d..6d5bbaf6a68 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreAnswer.java @@ -25,30 +25,31 @@ public class AttachPrimaryDataStoreAnswer extends Answer { private String uuid; private long capacity; private long avail; + public AttachPrimaryDataStoreAnswer(Command cmd) { super(cmd); } - + public void setUuid(String uuid) { this.uuid = uuid; } - + public String getUuid() { return this.uuid; } - + public void setCapacity(long capacity) { this.capacity = capacity; } - + public long getCapacity() { return this.capacity; } - + public void setAvailable(long avail) { this.avail = avail; } - + public long getAvailable() { return this.avail; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java index 15573a08a32..2083876b567 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/AttachPrimaryDataStoreCmd.java @@ -18,22 +18,22 @@ */ package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Command; -public class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { +public final class AttachPrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { private final String dataStore; + public AttachPrimaryDataStoreCmd(String uri) { + super(); this.dataStore = uri; } - + public String getDataStore() { return this.dataStore; } @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java b/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java index 129f6f82375..0a33c519f01 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CommandResult.java @@ -21,27 +21,28 @@ package org.apache.cloudstack.storage.command; public class CommandResult { private boolean success; private String result; + public CommandResult() { this.success = true; this.result = ""; } - + public boolean isSuccess() { return this.success; } - + public boolean isFailed() { return !this.success; } - + public void setSuccess(boolean success) { this.success = success; } - + public String getResult() { return this.result; } - + public void setResult(String result) { this.result = result; if (result != null) { @@ -49,4 +50,3 @@ public class CommandResult { } } } - \ No newline at end of file diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java index 132832af636..95c0e8990f8 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCmdAnswer.java @@ -16,23 +16,21 @@ // under the License. package org.apache.cloudstack.storage.command; - - import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataTO; public class CopyCmdAnswer extends Answer { private DataTO newData; - + public CopyCmdAnswer(DataTO newData) { super(null); this.newData = newData; } - + public DataTO getNewData() { return this.newData; } - + public CopyCmdAnswer(String errMsg) { super(null, false, errMsg); } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java index d512e60d779..852d8013c93 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CopyCommand.java @@ -16,11 +16,10 @@ // under the License. package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public class CopyCommand extends Command implements StorageSubSystemCommand { +public final class CopyCommand extends Command implements StorageSubSystemCommand { private DataTO srcTO; private DataTO destTO; private DataTO cacheTO; @@ -31,11 +30,11 @@ public class CopyCommand extends Command implements StorageSubSystemCommand { this.destTO = destData; this.setWait(timeout); } - + public DataTO getDestTO() { return this.destTO; } - + public DataTO getSrcTO() { return this.srcTO; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java index 2c174e4687f..b0c47447f6f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectAnswer.java @@ -18,12 +18,12 @@ */ package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataTO; -public class CreateObjectAnswer extends Answer { +public final class CreateObjectAnswer extends Answer { private DataTO data; + protected CreateObjectAnswer() { super(); } @@ -32,12 +32,12 @@ public class CreateObjectAnswer extends Answer { super(); this.data = data; } - + public DataTO getData() { return this.data; } - + public CreateObjectAnswer(String errMsg) { super(null, false, errMsg); - } + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java index dfadc2dcea1..a282a51e78a 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java @@ -18,11 +18,10 @@ */ package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public class CreateObjectCommand extends Command implements StorageSubSystemCommand { +public final class CreateObjectCommand extends Command implements StorageSubSystemCommand { private DataTO data; public CreateObjectCommand(DataTO obj) { @@ -39,7 +38,7 @@ public class CreateObjectCommand extends Command implements StorageSubSystemComm // TODO Auto-generated method stub return false; } - + public DataTO getData() { return this.data; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java b/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java index 59ed0a8c2ea..b536028927f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreatePrimaryDataStoreCmd.java @@ -16,22 +16,22 @@ // under the License. package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Command; -public class CreatePrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { +public final class CreatePrimaryDataStoreCmd extends Command implements StorageSubSystemCommand { private final String dataStore; + public CreatePrimaryDataStoreCmd(String uri) { + super(); this.dataStore = uri; } - + public String getDataStore() { return this.dataStore; } - + @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java index 41af42c58ab..76696da30ae 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DeleteCommand.java @@ -18,25 +18,26 @@ */ package org.apache.cloudstack.storage.command; - import com.cloud.agent.api.Command; import com.cloud.agent.api.to.DataTO; -public class DeleteCommand extends Command implements StorageSubSystemCommand { - private DataTO data; +public final class DeleteCommand extends Command implements StorageSubSystemCommand { + private DataTO data; + public DeleteCommand(DataTO data) { + super(); this.data = data; } - + protected DeleteCommand() { - + super(); } + @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } - + public DataTO getData() { return this.data; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java index 6606a7fd743..62ce2465ab5 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachAnswer.java @@ -21,8 +21,9 @@ package org.apache.cloudstack.storage.command; import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DiskTO; -public class DettachAnswer extends Answer { +public final class DettachAnswer extends Answer { private DiskTO disk; + public DettachAnswer() { super(null); } @@ -31,6 +32,7 @@ public class DettachAnswer extends Answer { super(null); this.setDisk(disk); } + public DettachAnswer(String errMsg) { super(null, false, errMsg); } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java index c435e102120..a0ab4b2e6f4 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DettachCommand.java @@ -24,29 +24,32 @@ import com.cloud.agent.api.to.DiskTO; public class DettachCommand extends Command implements StorageSubSystemCommand { private DiskTO disk; private String vmName; - + public DettachCommand(DiskTO disk, String vmName) { + super(); this.disk = disk; this.vmName = vmName; } - + @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } + public DiskTO getDisk() { return disk; } + public void setDisk(DiskTO disk) { this.disk = disk; } + public String getVmName() { return vmName; } + public void setVmName(String vmName) { this.vmName = vmName; } - } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java index 864f5b6a931..9528ff788d8 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/DownloadSystemTemplateCommand.java @@ -16,138 +16,114 @@ // under the License. package org.apache.cloudstack.storage.command; - - import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.PasswordAuth; import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.template.VirtualMachineTemplate; - public class DownloadSystemTemplateCommand extends Command { - - private PasswordAuth auth; - private Proxy _proxy; - private DataStoreTO _store; + private PasswordAuth auth; + private Proxy _proxy; + private DataStoreTO _store; private Long resourceId; private Long accountId; private String url; private Long maxDownloadSizeInBytes; private String name; - protected DownloadSystemTemplateCommand() { - } + protected DownloadSystemTemplateCommand() { + super(); + } - - - public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, VirtualMachineTemplate template, Long maxDownloadSizeInBytes) { - this._store = store; - this.accountId = template.getAccountId(); - this.url = secUrl; - this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; - this.resourceId = template.getId(); - this.name = template.getUniqueName(); - } - - - public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, String url, VirtualMachineTemplate template, String user, String passwd, Long maxDownloadSizeInBytes) { + public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, VirtualMachineTemplate template, + Long maxDownloadSizeInBytes) { + super(); this._store = store; this.accountId = template.getAccountId(); this.url = secUrl; this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; this.resourceId = template.getId(); - auth = new PasswordAuth(user, passwd); - this.name = template.getUniqueName(); - } + this.name = template.getUniqueName(); + } + public DownloadSystemTemplateCommand(DataStoreTO store, String secUrl, String url, VirtualMachineTemplate template, + String user, String passwd, Long maxDownloadSizeInBytes) { + super(); + this._store = store; + this.accountId = template.getAccountId(); + this.url = secUrl; + this.maxDownloadSizeInBytes = maxDownloadSizeInBytes; + this.resourceId = template.getId(); + auth = new PasswordAuth(user, passwd); + this.name = template.getUniqueName(); + } + public PasswordAuth getAuth() { + return auth; + } + public void setCreds(String userName, String passwd) { + auth = new PasswordAuth(userName, passwd); + } - public PasswordAuth getAuth() { - return auth; - } + public Proxy getProxy() { + return _proxy; + } - public void setCreds(String userName, String passwd) { - auth = new PasswordAuth(userName, passwd); - } - - public Proxy getProxy() { - return _proxy; - } - - public void setProxy(Proxy proxy) { - _proxy = proxy; - } - - public Long getMaxDownloadSizeInBytes() { - return maxDownloadSizeInBytes; - } + public void setProxy(Proxy proxy) { + _proxy = proxy; + } + public Long getMaxDownloadSizeInBytes() { + return maxDownloadSizeInBytes; + } public DataStoreTO getDataStore() { return _store; } - public void setDataStore(DataStoreTO _store) { this._store = _store; } - public Long getResourceId() { return resourceId; } - public void setResourceId(Long resourceId) { this.resourceId = resourceId; } - - public Long getAccountId() { return accountId; } - - public void setAccountId(Long accountId) { this.accountId = accountId; } - - public String getUrl() { return url; } - - public void setUrl(String url) { this.url = url; } - - public String getName() { return name; } - - public void setName(String name) { this.name = name; } - - @Override public boolean executeInSequence() { // TODO Auto-generated method stub return false; } - } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 4ac2ffc9c91..8d63a82be69 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -20,16 +20,18 @@ package org.apache.cloudstack.storage.datastore.db; import java.util.List; - import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; - import com.cloud.utils.db.GenericDao; public interface ImageStoreDao extends GenericDao { public ImageStoreVO findByName(String name); + public List findByProvider(String provider); + public List findByScope(ZoneScope scope); + public List findImageCacheByScope(ZoneScope scope); + public List listImageStores(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java index 63ac9e4f3f9..b9221489e05 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailVO.java @@ -26,20 +26,20 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="image_store_details") +@Table(name = "image_store_details") public class ImageStoreDetailVO implements InternalIdentity { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") long id; - @Column(name="store_id") + @Column(name = "store_id") long storeId; - @Column(name="name") + @Column(name = "name") String name; - @Column(name="value") + @Column(name = "value") String value; public ImageStoreDetailVO() { @@ -79,5 +79,4 @@ public class ImageStoreDetailVO implements InternalIdentity { this.value = value; } - } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java index 033a818faa7..91fff280d91 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDetailsDao.java @@ -18,7 +18,6 @@ package org.apache.cloudstack.storage.datastore.db; import java.util.Map; - import com.cloud.utils.db.GenericDao; public interface ImageStoreDetailsDao extends GenericDao { 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 fb320477603..3c903ad6e20 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 @@ -37,7 +37,8 @@ import com.cloud.utils.db.GenericDao; @Table(name = "image_store") public class ImageStoreVO implements ImageStore { @Id - @TableGenerator(name = "image_store_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "image_store_seq", allocationSize = 1) + @TableGenerator(name = "image_store_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", + pkColumnValue = "image_store_seq", allocationSize = 1) @Column(name = "id", nullable = false) private long id; @@ -76,7 +77,7 @@ public class ImageStoreVO implements ImageStore { @Column(name = "parent") private String parent; - @Column(name="total_size") + @Column(name = "total_size") private Long totalSize; public DataStoreRole getRole() { @@ -179,5 +180,4 @@ public class ImageStoreVO implements ImageStore { this.totalSize = totalSize; } - } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java index 16fed3586aa..5458de58725 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDao.java @@ -20,93 +20,104 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; - import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.GenericDao; + /** * Data Access Object for storage_pool table */ public interface PrimaryDataStoreDao extends GenericDao { - /** - * @param datacenterId -- the id of the datacenter (availability zone) - */ - List listByDataCenterId(long datacenterId); - - /** - * @param datacenterId -- the id of the datacenter (availability zone) - */ - List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope); - - /** - * Set capacity of storage pool in bytes - * @param id pool id. - * @param capacity capacity in bytes - */ + /** + * @param datacenterId + * -- the id of the datacenter (availability zone) + */ + List listByDataCenterId(long datacenterId); + + /** + * @param datacenterId + * -- the id of the datacenter (availability zone) + */ + List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope); + + /** + * Set capacity of storage pool in bytes + * + * @param id + * pool id. + * @param capacity + * capacity in bytes + */ void updateCapacity(long id, long capacity); - - /** - * Set available bytes of storage pool in bytes - * @param id pool id. - * @param available available capacity in bytes - */ + + /** + * Set available bytes of storage pool in bytes + * + * @param id + * pool id. + * @param available + * available capacity in bytes + */ void updateAvailable(long id, long available); - - + StoragePoolVO persist(StoragePoolVO pool, Map details); - + /** * Find pool by name. * - * @param name name of pool. - * @return the single StoragePoolVO + * @param name + * name of pool. + * @return the single StoragePoolVO */ List findPoolByName(String name); - + /** * Find pools by the pod that matches the details. * - * @param podId pod id to find the pools in. - * @param details details to match. All must match for the pool to be returned. + * @param podId + * pod id to find the pools in. + * @param details + * details to match. All must match for the pool to be returned. * @return List of StoragePoolVO */ - List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, ScopeType scope); - + List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, + ScopeType scope); + List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags); - + /** * Find pool by UUID. * - * @param uuid uuid of pool. - * @return the single StoragePoolVO + * @param uuid + * uuid of pool. + * @return the single StoragePoolVO */ StoragePoolVO findPoolByUUID(String uuid); List listByStorageHost(String hostFqdnOrIp); StoragePoolVO findPoolByHostPath(long dcId, Long podId, String host, String path, String uuid); - + List listPoolByHostPath(String host, String path); - + void updateDetails(long poolId, Map details); - + Map getDetails(long poolId); - List searchForStoragePoolDetails(long poolId, String value); - - List findIfDuplicatePoolsExistByUUID(String uuid); + List searchForStoragePoolDetails(long poolId, String value); + + List findIfDuplicatePoolsExistByUUID(String uuid); List listByStatus(StoragePoolStatus status); long countPoolsByStatus(StoragePoolStatus... statuses); - List listByStatusInZone(long dcId, StoragePoolStatus status); - + List listByStatusInZone(long dcId, StoragePoolStatus status); + List listPoolsByCluster(long clusterId); - List findLocalStoragePoolsByTags(long dcId, long podId, - Long clusterId, String[] tags); + List findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags); - List findZoneWideStoragePoolsByTags(long dcId, String[] tags); + List findZoneWideStoragePoolsByTags(long dcId, String[] tags); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 7e7e6fd4002..5d6e2cf9b72 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -48,141 +48,136 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @Component -@Local(value={PrimaryDataStoreDao.class}) @DB(txn=false) -public class PrimaryDataStoreDaoImpl extends GenericDaoBase implements PrimaryDataStoreDao { +@Local(value = { PrimaryDataStoreDao.class }) +@DB(txn = false) +public class PrimaryDataStoreDaoImpl extends GenericDaoBase implements PrimaryDataStoreDao { protected final SearchBuilder AllFieldSearch; - protected final SearchBuilder DcPodSearch; + protected final SearchBuilder DcPodSearch; protected final SearchBuilder DcPodAnyClusterSearch; protected final SearchBuilder DeleteLvmSearch; protected final GenericSearchBuilder StatusCountSearch; - - @Inject protected StoragePoolDetailsDao _detailsDao; - + + @Inject + protected StoragePoolDetailsDao _detailsDao; + private final String DetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and (storage_pool.pod_id = ? or storage_pool.pod_id is null) and storage_pool.scope = ? and ("; - private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; - private final String ZoneWideDetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and ("; - private final String ZoneWideDetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; - - private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?"; - + private final String DetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; + private final String ZoneWideDetailsSqlPrefix = "SELECT storage_pool.* from storage_pool LEFT JOIN storage_pool_details ON storage_pool.id = storage_pool_details.pool_id WHERE storage_pool.removed is null and storage_pool.status = 'Up' and storage_pool.data_center_id = ? and storage_pool.scope = ? and ("; + private final String ZoneWideDetailsSqlSuffix = ") GROUP BY storage_pool_details.pool_id HAVING COUNT(storage_pool_details.name) >= ?"; + + private final String FindPoolTagDetails = "SELECT storage_pool_details.name FROM storage_pool_details WHERE pool_id = ? and value = ?"; + public PrimaryDataStoreDaoImpl() { AllFieldSearch = createSearchBuilder(); AllFieldSearch.and("name", AllFieldSearch.entity().getName(), SearchCriteria.Op.EQ); AllFieldSearch.and("uuid", AllFieldSearch.entity().getUuid(), SearchCriteria.Op.EQ); AllFieldSearch.and("datacenterId", AllFieldSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); AllFieldSearch.and("hostAddress", AllFieldSearch.entity().getHostAddress(), SearchCriteria.Op.EQ); - AllFieldSearch.and("status",AllFieldSearch.entity().getStatus(),SearchCriteria.Op.EQ); + AllFieldSearch.and("status", AllFieldSearch.entity().getStatus(), SearchCriteria.Op.EQ); AllFieldSearch.and("path", AllFieldSearch.entity().getPath(), SearchCriteria.Op.EQ); AllFieldSearch.and("podId", AllFieldSearch.entity().getPodId(), Op.EQ); AllFieldSearch.and("clusterId", AllFieldSearch.entity().getClusterId(), Op.EQ); - AllFieldSearch.done(); - - DcPodSearch = createSearchBuilder(); - DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ); - DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ); - DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL); - DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); - DcPodSearch.cp(); - DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL); - DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ); - DcPodSearch.cp(); - DcPodSearch.done(); - - DcPodAnyClusterSearch = createSearchBuilder(); - DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + AllFieldSearch.done(); + + DcPodSearch = createSearchBuilder(); + DcPodSearch.and("datacenterId", DcPodSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + DcPodSearch.and("status", DcPodSearch.entity().getStatus(), SearchCriteria.Op.EQ); + DcPodSearch.and("scope", DcPodSearch.entity().getScope(), SearchCriteria.Op.EQ); + DcPodSearch.and().op("nullpod", DcPodSearch.entity().getPodId(), SearchCriteria.Op.NULL); + DcPodSearch.or("podId", DcPodSearch.entity().getPodId(), SearchCriteria.Op.EQ); + DcPodSearch.cp(); + DcPodSearch.and().op("nullcluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.NULL); + DcPodSearch.or("cluster", DcPodSearch.entity().getClusterId(), SearchCriteria.Op.EQ); + DcPodSearch.cp(); + DcPodSearch.done(); + + DcPodAnyClusterSearch = createSearchBuilder(); + DcPodAnyClusterSearch.and("datacenterId", DcPodAnyClusterSearch.entity().getDataCenterId(), + SearchCriteria.Op.EQ); DcPodAnyClusterSearch.and("status", DcPodAnyClusterSearch.entity().getStatus(), SearchCriteria.Op.EQ); DcPodAnyClusterSearch.and("scope", DcPodAnyClusterSearch.entity().getScope(), SearchCriteria.Op.EQ); DcPodAnyClusterSearch.and().op("nullpod", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.NULL); DcPodAnyClusterSearch.or("podId", DcPodAnyClusterSearch.entity().getPodId(), SearchCriteria.Op.EQ); DcPodAnyClusterSearch.cp(); DcPodAnyClusterSearch.done(); - + DeleteLvmSearch = createSearchBuilder(); DeleteLvmSearch.and("ids", DeleteLvmSearch.entity().getId(), SearchCriteria.Op.IN); DeleteLvmSearch.and().op("LVM", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ); DeleteLvmSearch.or("Filesystem", DeleteLvmSearch.entity().getPoolType(), SearchCriteria.Op.EQ); DeleteLvmSearch.cp(); - DeleteLvmSearch.done(); + DeleteLvmSearch.done(); - - StatusCountSearch = createSearchBuilder(Long.class); StatusCountSearch.and("status", StatusCountSearch.entity().getStatus(), SearchCriteria.Op.IN); StatusCountSearch.select(null, Func.COUNT, null); StatusCountSearch.done(); } - - @Override - public List findPoolByName(String name) { - SearchCriteria sc = AllFieldSearch.create(); + + @Override + public List findPoolByName(String name) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("name", name); return listIncludingRemovedBy(sc); - } + } - - @Override - public StoragePoolVO findPoolByUUID(String uuid) { - SearchCriteria sc = AllFieldSearch.create(); + @Override + public StoragePoolVO findPoolByUUID(String uuid) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("uuid", uuid); return findOneIncludingRemovedBy(sc); - } - - + } - @Override - public List findIfDuplicatePoolsExistByUUID(String uuid) { - SearchCriteria sc = AllFieldSearch.create(); + @Override + public List findIfDuplicatePoolsExistByUUID(String uuid) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("uuid", uuid); return listBy(sc); - } + } - - @Override - public List listByDataCenterId(long datacenterId) { - SearchCriteria sc = AllFieldSearch.create(); + @Override + public List listByDataCenterId(long datacenterId) { + SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("datacenterId", datacenterId); return listBy(sc); - } + } + @Override + public void updateAvailable(long id, long available) { + StoragePoolVO pool = createForUpdate(id); + pool.setAvailableBytes(available); + update(id, pool); + } - @Override - public void updateAvailable(long id, long available) { - StoragePoolVO pool = createForUpdate(id); - pool.setAvailableBytes(available); - update(id, pool); - } + @Override + public void updateCapacity(long id, long capacity) { + StoragePoolVO pool = createForUpdate(id); + pool.setCapacityBytes(capacity); + update(id, pool); + } - @Override - public void updateCapacity(long id, long capacity) { - StoragePoolVO pool = createForUpdate(id); - pool.setCapacityBytes(capacity); - update(id, pool); - - } - @Override public List listByStorageHost(String hostFqdnOrIp) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("hostAddress", hostFqdnOrIp); return listIncludingRemovedBy(sc); } - + @Override - public List listByStatus(StoragePoolStatus status){ + public List listByStatus(StoragePoolStatus status) { SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("status", status); - return listBy(sc); + sc.setParameters("status", status); + return listBy(sc); } - + @Override - public List listByStatusInZone(long dcId, StoragePoolStatus status){ + public List listByStatusInZone(long dcId, StoragePoolStatus status) { SearchCriteria sc = AllFieldSearch.create(); - sc.setParameters("status", status); - sc.setParameters("datacenterId", dcId); - return listBy(sc); + sc.setParameters("status", status); + sc.setParameters("datacenterId", dcId); + return listBy(sc); } @Override @@ -193,238 +188,239 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase sc.setParameters("datacenterId", datacenterId); sc.setParameters("podId", podId); sc.setParameters("uuid", uuid); - + return findOneBy(sc); } - @Override - public List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope) { - if (clusterId != null) { - SearchCriteria sc = DcPodSearch.create(); + @Override + public List listBy(long datacenterId, long podId, Long clusterId, ScopeType scope) { + if (clusterId != null) { + SearchCriteria sc = DcPodSearch.create(); sc.setParameters("datacenterId", datacenterId); sc.setParameters("podId", podId); sc.setParameters("status", Status.Up); sc.setParameters("scope", scope); - + sc.setParameters("cluster", clusterId); return listBy(sc); - } else { - SearchCriteria sc = DcPodAnyClusterSearch.create(); - sc.setParameters("datacenterId", datacenterId); - sc.setParameters("podId", podId); - sc.setParameters("status", Status.Up); - sc.setParameters("scope", scope); - return listBy(sc); - } - } + } else { + SearchCriteria sc = DcPodAnyClusterSearch.create(); + sc.setParameters("datacenterId", datacenterId); + sc.setParameters("podId", podId); + sc.setParameters("status", Status.Up); + sc.setParameters("scope", scope); + return listBy(sc); + } + } - @Override - public List listPoolByHostPath(String host, String path) { + @Override + public List listPoolByHostPath(String host, String path) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("hostAddress", host); sc.setParameters("path", path); - + return listBy(sc); - } - - public StoragePoolVO listById(Integer id) - { + } + + public StoragePoolVO listById(Integer id) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("id", id); - + return findOneIncludingRemovedBy(sc); - } - - @Override @DB - public StoragePoolVO persist(StoragePoolVO pool, Map details) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - pool = super.persist(pool); - if (details != null) { - for (Map.Entry detail : details.entrySet()) { - StoragePoolDetailVO vo = new StoragePoolDetailVO(pool.getId(), detail.getKey(), detail.getValue()); - _detailsDao.persist(vo); - } - } - txn.commit(); - return pool; - } - - @DB - @Override - public List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, ScopeType scope) { - StringBuilder sql = new StringBuilder(DetailsSqlPrefix); - if (clusterId != null) { - sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND ("); - } - - for (Map.Entry detail : details.entrySet()) { - sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); - } - sql.delete(sql.length() - 4, sql.length()); - sql.append(DetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - int i = 1; - pstmt.setLong(i++, dcId); - pstmt.setLong(i++, podId); - pstmt.setString(i++, scope.toString()); - if (clusterId != null) { - pstmt.setLong(i++, clusterId); - } - pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); - List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); - } - return pools; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); - } - } - - protected Map tagsToDetails(String[] tags) { - Map details = new HashMap(tags.length); - for (String tag: tags) { - details.put(tag, "true"); - } - return details; - } - - @Override - public List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { - List storagePools = null; - if (tags == null || tags.length == 0) { - storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER); - } else { - Map details = tagsToDetails(tags); - storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.CLUSTER); - } - - return storagePools; - } - - @Override - public List findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { - List storagePools = null; - if (tags == null || tags.length == 0) { - storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST); - } else { - Map details = tagsToDetails(tags); - storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.HOST); - } - - return storagePools; - } - - @Override - public List findZoneWideStoragePoolsByTags(long dcId, String[] tags) { - List storagePools = null; - if (tags == null || tags.length == 0) { - SearchCriteriaService sc = SearchCriteria2.create(StoragePoolVO.class); - sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); - sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); - sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE); - return sc.list(); - } else { - Map details = tagsToDetails(tags); - - StringBuilder sql = new StringBuilder(ZoneWideDetailsSqlPrefix); - - for (Map.Entry detail : details.entrySet()) { - sql.append("((storage_pool_details.name='").append(detail.getKey()).append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); - } - sql.delete(sql.length() - 4, sql.length()); - sql.append(ZoneWideDetailsSqlSuffix); - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - int i = 1; - pstmt.setLong(i++, dcId); - pstmt.setString(i++, ScopeType.ZONE.toString()); - pstmt.setInt(i++, details.size()); - ResultSet rs = pstmt.executeQuery(); - List pools = new ArrayList(); - while (rs.next()) { - pools.add(toEntityBean(rs, false)); - } - return pools; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt, e); - } - } - } - - @Override - @DB - public List searchForStoragePoolDetails(long poolId, String value){ - - StringBuilder sql = new StringBuilder(FindPoolTagDetails); - - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - pstmt = txn.prepareAutoCloseStatement(sql.toString()); - pstmt.setLong(1, poolId); - pstmt.setString(2, value); - - ResultSet rs = pstmt.executeQuery(); - List tags = new ArrayList(); - - while (rs.next()) { - tags.add(rs.getString("name")); - } - return tags; - } catch (SQLException e) { - throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); - } - - } - - @Override - public void updateDetails(long poolId, Map details) { - if (details != null) { - _detailsDao.update(poolId, details); - } } - - @Override - public Map getDetails(long poolId) { - return _detailsDao.getDetails(poolId); - } - - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - super.configure(name, params); - _detailsDao.configure("DetailsDao", params); - return true; - } - - - + @Override - public long countPoolsByStatus( StoragePoolStatus... statuses) { + @DB + public StoragePoolVO persist(StoragePoolVO pool, Map details) { + Transaction txn = Transaction.currentTxn(); + txn.start(); + pool = super.persist(pool); + if (details != null) { + for (Map.Entry detail : details.entrySet()) { + StoragePoolDetailVO vo = new StoragePoolDetailVO(pool.getId(), detail.getKey(), detail.getValue()); + _detailsDao.persist(vo); + } + } + txn.commit(); + return pool; + } + + @DB + @Override + public List findPoolsByDetails(long dcId, long podId, Long clusterId, Map details, + ScopeType scope) { + StringBuilder sql = new StringBuilder(DetailsSqlPrefix); + if (clusterId != null) { + sql.append("storage_pool.cluster_id = ? OR storage_pool.cluster_id IS NULL) AND ("); + } + + for (Map.Entry detail : details.entrySet()) { + sql.append("((storage_pool_details.name='").append(detail.getKey()) + .append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); + } + sql.delete(sql.length() - 4, sql.length()); + sql.append(DetailsSqlSuffix); + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + int i = 1; + pstmt.setLong(i++, dcId); + pstmt.setLong(i++, podId); + pstmt.setString(i++, scope.toString()); + if (clusterId != null) { + pstmt.setLong(i++, clusterId); + } + pstmt.setInt(i++, details.size()); + ResultSet rs = pstmt.executeQuery(); + List pools = new ArrayList(); + while (rs.next()) { + pools.add(toEntityBean(rs, false)); + } + return pools; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt, e); + } + } + + protected Map tagsToDetails(String[] tags) { + Map details = new HashMap(tags.length); + for (String tag : tags) { + details.put(tag, "true"); + } + return details; + } + + @Override + public List findPoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { + List storagePools = null; + if (tags == null || tags.length == 0) { + storagePools = listBy(dcId, podId, clusterId, ScopeType.CLUSTER); + } else { + Map details = tagsToDetails(tags); + storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.CLUSTER); + } + + return storagePools; + } + + @Override + public List findLocalStoragePoolsByTags(long dcId, long podId, Long clusterId, String[] tags) { + List storagePools = null; + if (tags == null || tags.length == 0) { + storagePools = listBy(dcId, podId, clusterId, ScopeType.HOST); + } else { + Map details = tagsToDetails(tags); + storagePools = findPoolsByDetails(dcId, podId, clusterId, details, ScopeType.HOST); + } + + return storagePools; + } + + @Override + public List findZoneWideStoragePoolsByTags(long dcId, String[] tags) { + List storagePools = null; + if (tags == null || tags.length == 0) { + SearchCriteriaService sc = SearchCriteria2.create(StoragePoolVO.class); + sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId); + sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); + sc.addAnd(sc.getEntity().getScope(), Op.EQ, ScopeType.ZONE); + return sc.list(); + } else { + Map details = tagsToDetails(tags); + + StringBuilder sql = new StringBuilder(ZoneWideDetailsSqlPrefix); + + for (Map.Entry detail : details.entrySet()) { + sql.append("((storage_pool_details.name='").append(detail.getKey()) + .append("') AND (storage_pool_details.value='").append(detail.getValue()).append("')) OR "); + } + sql.delete(sql.length() - 4, sql.length()); + sql.append(ZoneWideDetailsSqlSuffix); + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + int i = 1; + pstmt.setLong(i++, dcId); + pstmt.setString(i++, ScopeType.ZONE.toString()); + pstmt.setInt(i++, details.size()); + ResultSet rs = pstmt.executeQuery(); + List pools = new ArrayList(); + while (rs.next()) { + pools.add(toEntityBean(rs, false)); + } + return pools; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt, e); + } + } + } + + @Override + @DB + public List searchForStoragePoolDetails(long poolId, String value) { + + StringBuilder sql = new StringBuilder(FindPoolTagDetails); + + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + pstmt = txn.prepareAutoCloseStatement(sql.toString()); + pstmt.setLong(1, poolId); + pstmt.setString(2, value); + + ResultSet rs = pstmt.executeQuery(); + List tags = new ArrayList(); + + while (rs.next()) { + tags.add(rs.getString("name")); + } + return tags; + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to execute " + pstmt.toString(), e); + } + + } + + @Override + public void updateDetails(long poolId, Map details) { + if (details != null) { + _detailsDao.update(poolId, details); + } + } + + @Override + public Map getDetails(long poolId) { + return _detailsDao.getDetails(poolId); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + _detailsDao.configure("DetailsDao", params); + return true; + } + + @Override + public long countPoolsByStatus(StoragePoolStatus... statuses) { SearchCriteria sc = StatusCountSearch.create(); - - sc.setParameters("status", (Object[])statuses); - + + sc.setParameters("status", (Object[]) statuses); + List rs = customSearchIncludingRemoved(sc, null); if (rs.size() == 0) { return 0; } - + return rs.get(0); } - + @Override public List listPoolsByCluster(long clusterId) { SearchCriteria sc = AllFieldSearch.create(); sc.setParameters("clusterId", clusterId); - + return listBy(sc); } } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java index d1f802de949..0d9af4b5fb3 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailVO.java @@ -24,28 +24,28 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="storage_pool_details") +@Table(name = "storage_pool_details") public class PrimaryDataStoreDetailVO { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") long id; - - @Column(name="pool_id") + + @Column(name = "pool_id") long poolId; - - @Column(name="name") + + @Column(name = "name") String name; - - @Column(name="value") + + @Column(name = "value") String value; - + public PrimaryDataStoreDetailVO(long poolId, String name, String value) { this.poolId = poolId; this.name = name; this.value = value; } - + public long getId() { return id; } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java index c2b109a959e..18e2f1c7018 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDetailsDao.java @@ -21,7 +21,8 @@ import java.util.Map; import com.cloud.utils.db.GenericDao; public interface PrimaryDataStoreDetailsDao extends GenericDao { - + void update(long poolId, Map details); + Map getDetails(long poolId); } \ No newline at end of file diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index f5b46aaa85a..48d0db28127 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -16,18 +16,17 @@ // under the License. package org.apache.cloudstack.storage.datastore.db; - import java.util.List; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; - import com.cloud.storage.DataStoreRole; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface SnapshotDataStoreDao extends GenericDao, StateDao { +public interface SnapshotDataStoreDao extends GenericDao, + StateDao { public List listByStoreId(long id, DataStoreRole role); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index edb23d034f9..6ceb0d0fcba 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -40,49 +40,48 @@ import com.cloud.utils.fsm.StateObject; /** * Join table for image_data_store and snapshots - * + * */ @Entity -@Table(name="snapshot_store_ref") +@Table(name = "snapshot_store_ref") public class SnapshotDataStoreVO implements StateObject, DataObjectInStore { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; - @Column(name="store_id") - private long dataStoreId; + @Column(name = "store_id") + private long dataStoreId; - @Column(name="store_role") - @Enumerated(EnumType.STRING) - private DataStoreRole role; + @Column(name = "store_role") + @Enumerated(EnumType.STRING) + private DataStoreRole role; - @Column(name="snapshot_id") - private long snapshotId; + @Column(name = "snapshot_id") + private long snapshotId; - @Column(name=GenericDaoBase.CREATED_COLUMN) - private Date created = null; + @Column(name = GenericDaoBase.CREATED_COLUMN) + private Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) - private Date lastUpdated = null; + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) + private Date lastUpdated = null; - @Column (name="size") - private long size; + @Column(name = "size") + private long size; - @Column (name="physical_size") - private long physicalSize; + @Column(name = "physical_size") + private long physicalSize; - @Column(name="parent_snapshot_id") - private long parentSnapshotId; + @Column(name = "parent_snapshot_id") + private long parentSnapshotId; - @Column (name="job_id") - private String jobId; + @Column(name = "job_id") + private String jobId; - @Column (name="install_path") + @Column(name = "install_path") private String installPath; - - @Column(name="update_count", updatable = true, nullable=false) + @Column(name = "update_count", updatable = true, nullable = false) protected long updatedCount; @Column(name = "updated") @@ -94,97 +93,78 @@ public class SnapshotDataStoreVO implements StateObject { - + void update(long poolId, Map details); + Map getDetails(long poolId); + StoragePoolDetailVO findDetail(long poolId, String name); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java index 6a7c8544c53..78a5779f167 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/StoragePoolVO.java @@ -29,7 +29,6 @@ import javax.persistence.TableGenerator; import javax.persistence.Temporal; import javax.persistence.TemporalType; - import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.ScopeType; import com.cloud.storage.StoragePool; @@ -37,10 +36,11 @@ import com.cloud.storage.StoragePoolStatus; import com.cloud.utils.db.GenericDao; @Entity -@Table(name="storage_pool") -public class StoragePoolVO implements StoragePool{ +@Table(name = "storage_pool") +public class StoragePoolVO implements StoragePool { @Id - @TableGenerator(name = "storage_pool_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "storage_pool_seq", allocationSize = 1) + @TableGenerator(name = "storage_pool_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", + pkColumnValue = "storage_pool_seq", allocationSize = 1) @Column(name = "id", updatable = false, nullable = false) private long id; @@ -113,10 +113,10 @@ public class StoragePoolVO implements StoragePool{ public StoragePoolVO() { this.status = StoragePoolStatus.Initial; } - - public StoragePoolVO(long poolId, String name, String uuid, StoragePoolType type, - long dataCenterId, Long podId, long availableBytes, long capacityBytes, String hostAddress, int port, String hostPath) { - this.name = name; + + public StoragePoolVO(long poolId, String name, String uuid, StoragePoolType type, long dataCenterId, Long podId, + long availableBytes, long capacityBytes, String hostAddress, int port, String hostPath) { + this.name = name; this.id = poolId; this.uuid = uuid; this.poolType = type; @@ -131,7 +131,8 @@ public class StoragePoolVO implements StoragePool{ } public StoragePoolVO(StoragePoolVO that) { - this(that.id, that.name, that.uuid, that.poolType, that.dataCenterId, that.podId, that.availableBytes, that.capacityBytes, that.hostAddress, that.port, that.path); + this(that.id, that.name, that.uuid, that.poolType, that.dataCenterId, that.podId, that.availableBytes, + that.capacityBytes, that.hostAddress, that.port, that.path); } public StoragePoolVO(StoragePoolType type, String hostAddress, int port, String path) { @@ -143,7 +144,6 @@ public class StoragePoolVO implements StoragePool{ this.uuid = UUID.randomUUID().toString(); } - public String getName() { return name; } @@ -294,11 +294,11 @@ public class StoragePoolVO implements StoragePool{ public String toString() { return new StringBuilder("Pool[").append(id).append("|").append(poolType).append("]").toString(); } - + public boolean isShared() { return this.scope == ScopeType.HOST ? false : true; } - + public boolean isLocal() { return !isShared(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java index b83c590266f..79acd319ab5 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java @@ -22,14 +22,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; - import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface TemplateDataStoreDao extends GenericDao, StateDao { - +public interface TemplateDataStoreDao extends GenericDao, + StateDao { public List listByStoreId(long id); @@ -43,11 +42,14 @@ public interface TemplateDataStoreDao extends GenericDao listByTemplateStoreStatus(long templateId, long storeId, State... states); - List listByTemplateStoreDownloadStatus(long templateId, long storeId, VMTemplateStorageResourceAssoc.Status... status); + List listByTemplateStoreDownloadStatus(long templateId, long storeId, + VMTemplateStorageResourceAssoc.Status... status); - List listByTemplateZoneDownloadStatus(long templateId, Long zoneId, VMTemplateStorageResourceAssoc.Status... status); + List listByTemplateZoneDownloadStatus(long templateId, Long zoneId, + VMTemplateStorageResourceAssoc.Status... status); - TemplateDataStoreVO findByTemplateZoneDownloadStatus(long templateId, Long zoneId, VMTemplateStorageResourceAssoc.Status... status); + TemplateDataStoreVO findByTemplateZoneDownloadStatus(long templateId, Long zoneId, + VMTemplateStorageResourceAssoc.Status... status); TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index 44bda70a00b..2cee4d13e8e 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -41,67 +41,67 @@ import com.cloud.utils.fsm.StateObject; /** * Join table for image_data_store and templates - * + * */ @Entity -@Table(name="template_store_ref") +@Table(name = "template_store_ref") public class TemplateDataStoreVO implements StateObject, DataObjectInStore { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; - @Column(name="store_id") - private Long dataStoreId; // this can be null for baremetal templates + @Column(name = "store_id") + private Long dataStoreId; // this can be null for baremetal templates - @Column(name="template_id") - private long templateId; + @Column(name = "template_id") + private long templateId; - @Column(name="store_role") + @Column(name = "store_role") @Enumerated(EnumType.STRING) private DataStoreRole dataStoreRole; - @Column(name=GenericDaoBase.CREATED_COLUMN) - private Date created = null; + @Column(name = GenericDaoBase.CREATED_COLUMN) + private Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) - private Date lastUpdated = null; + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) + private Date lastUpdated = null; - @Column (name="download_pct") - private int downloadPercent; + @Column(name = "download_pct") + private int downloadPercent; - @Column (name="size") - private long size; + @Column(name = "size") + private long size; - @Column (name="physical_size") - private long physicalSize; + @Column(name = "physical_size") + private long physicalSize; - @Column (name="download_state") - @Enumerated(EnumType.STRING) - private Status downloadState; + @Column(name = "download_state") + @Enumerated(EnumType.STRING) + private Status downloadState; - @Column (name="local_path") - private String localDownloadPath; + @Column(name = "local_path") + private String localDownloadPath; - @Column (name="error_str") - private String errorString; + @Column(name = "error_str") + private String errorString; - @Column (name="job_id") - private String jobId; + @Column(name = "job_id") + private String jobId; - @Column (name="install_path") + @Column(name = "install_path") private String installPath; - @Column (name="url") - private String downloadUrl; + @Column(name = "url") + private String downloadUrl; - @Column(name="is_copy") - private boolean isCopy = false; + @Column(name = "is_copy") + private boolean isCopy = false; - @Column(name="destroyed") + @Column(name = "destroyed") boolean destroyed = false; - @Column(name="update_count", updatable = true, nullable=false) + @Column(name = "update_count", updatable = true, nullable = false) protected long updatedCount; @Column(name = "updated") @@ -112,31 +112,27 @@ public class TemplateDataStoreVO implements StateObject, StateDao { +public interface VolumeDataStoreDao extends GenericDao, + StateDao { public List listByStoreId(long id); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index 7e89de44e9e..d2e5c2585e1 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -41,66 +41,66 @@ import com.cloud.utils.fsm.StateObject; /** * Join table for image_data_store and volumes - * + * */ @Entity -@Table(name="volume_store_ref") +@Table(name = "volume_store_ref") public class VolumeDataStoreVO implements StateObject, DataObjectInStore { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; - @Column(name="store_id") - private long dataStoreId; + @Column(name = "store_id") + private long dataStoreId; - @Column(name="volume_id") - private long volumeId; + @Column(name = "volume_id") + private long volumeId; - @Column(name="zone_id") - private long zoneId; + @Column(name = "zone_id") + private long zoneId; - @Column(name=GenericDaoBase.CREATED_COLUMN) - private Date created = null; + @Column(name = GenericDaoBase.CREATED_COLUMN) + private Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) - private Date lastUpdated = null; + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) + private Date lastUpdated = null; - @Column (name="download_pct") - private int downloadPercent; + @Column(name = "download_pct") + private int downloadPercent; - @Column (name="size") - private long size; + @Column(name = "size") + private long size; - @Column (name="physical_size") - private long physicalSize; + @Column(name = "physical_size") + private long physicalSize; - @Column (name="download_state") - @Enumerated(EnumType.STRING) - private Status downloadState; + @Column(name = "download_state") + @Enumerated(EnumType.STRING) + private Status downloadState; - @Column(name="checksum") + @Column(name = "checksum") private String checksum; - @Column (name="local_path") - private String localDownloadPath; + @Column(name = "local_path") + private String localDownloadPath; - @Column (name="error_str") - private String errorString; + @Column(name = "error_str") + private String errorString; - @Column (name="job_id") - private String jobId; + @Column(name = "job_id") + private String jobId; - @Column (name="install_path") + @Column(name = "install_path") private String installPath; - @Column (name="url") - private String downloadUrl; + @Column(name = "url") + private String downloadUrl; - @Column(name="destroyed") + @Column(name = "destroyed") boolean destroyed = false; - @Column(name="update_count", updatable = true, nullable=false) + @Column(name = "update_count", updatable = true, nullable = false) protected long updatedCount; @Column(name = "updated") @@ -112,164 +112,144 @@ public class VolumeDataStoreVO implements StateObject listTemplates(); + String getMountPoint(); // get the mount point on ssvm. } diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java index c5f7ca98c1d..d51780da566 100644 --- a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreInfo.java @@ -22,5 +22,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; public interface ImageStoreInfo extends DataStore { public long getImageStoreId(); + public String getType(); } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java index 96e94794c57..45d0e98aa8f 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/ImageStoreTO.java @@ -27,7 +27,7 @@ public class ImageStoreTO implements DataStoreTO { private String providerName; private DataStoreRole role; - public ImageStoreTO(){ + public ImageStoreTO() { } @@ -53,7 +53,6 @@ public class ImageStoreTO implements DataStoreTO { return providerName; } - public void setType(String type) { this.type = type; } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java deleted file mode 100644 index 96fb6bb2401..00000000000 --- a/engine/api/src/org/apache/cloudstack/storage/to/NfsPrimaryDataStoreTO.java +++ /dev/null @@ -1,44 +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.to; - -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; - -public class NfsPrimaryDataStoreTO extends PrimaryDataStoreTO { - private String server; - private String path; - - public NfsPrimaryDataStoreTO(PrimaryDataStoreInfo dataStore) { - super(dataStore); - } - - public void setServer(String server) { - this.server = server; - } - - public String getServer() { - return this.server; - } - - public void setPath(String path) { - this.path = path; - } - - public String getPath() { - return this.path; - } -} diff --git a/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java b/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java index c3ce0e086d4..1b4c08ffeb8 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java @@ -25,35 +25,35 @@ import com.cloud.storage.Storage.StoragePoolType; public class PrimaryDataStoreTO implements DataStoreTO { private final String uuid; private final String name; - private String type; + private String type; private final long id; private StoragePoolType poolType; private String host; private String path; private int port; + public PrimaryDataStoreTO(PrimaryDataStoreInfo dataStore) { this.uuid = dataStore.getUuid(); this.name = dataStore.getName(); - // this.type = dataStore.getType(); this.id = dataStore.getId(); this.setPoolType(dataStore.getPoolType()); this.setHost(dataStore.getHostAddress()); this.setPath(dataStore.getPath()); this.setPort(dataStore.getPort()); } - + public long getId() { return this.id; } - + public String getUuid() { return this.uuid; } - + public String getName() { return this.name; } - + public String getType() { return this.type; } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java index 492bd06d67f..f8f622c9307 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -24,50 +24,50 @@ import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; public class SnapshotObjectTO implements DataTO { - private String path; - private VolumeObjectTO volume; - private String parentSnapshotPath; - private DataStoreTO dataStore; - private String vmName; - private String name; - private HypervisorType hypervisorType; - private long id; - - public SnapshotObjectTO() { - - } - - public SnapshotObjectTO(SnapshotInfo snapshot) { - this.path = snapshot.getPath(); - this.setId(snapshot.getId()); - this.volume = (VolumeObjectTO)snapshot.getBaseVolume().getTO(); - this.setVmName(snapshot.getBaseVolume().getAttachedVmName()); - if (snapshot.getParent() != null) { - this.parentSnapshotPath = snapshot.getParent().getPath(); - } - this.dataStore = snapshot.getDataStore().getTO(); - this.setName(snapshot.getName()); - this.hypervisorType = snapshot.getHypervisorType(); - } - - @Override - public DataObjectType getObjectType() { - return DataObjectType.SNAPSHOT; - } + private String path; + private VolumeObjectTO volume; + private String parentSnapshotPath; + private DataStoreTO dataStore; + private String vmName; + private String name; + private HypervisorType hypervisorType; + private long id; - @Override - public DataStoreTO getDataStore() { - return this.dataStore; - } + public SnapshotObjectTO() { - @Override - public String getPath() { - return this.path; - } - - public void setPath(String path) { - this.path = path; - } + } + + public SnapshotObjectTO(SnapshotInfo snapshot) { + this.path = snapshot.getPath(); + this.setId(snapshot.getId()); + this.volume = (VolumeObjectTO) snapshot.getBaseVolume().getTO(); + this.setVmName(snapshot.getBaseVolume().getAttachedVmName()); + if (snapshot.getParent() != null) { + this.parentSnapshotPath = snapshot.getParent().getPath(); + } + this.dataStore = snapshot.getDataStore().getTO(); + this.setName(snapshot.getName()); + this.hypervisorType = snapshot.getHypervisorType(); + } + + @Override + public DataObjectType getObjectType() { + return DataObjectType.SNAPSHOT; + } + + @Override + public DataStoreTO getDataStore() { + return this.dataStore; + } + + @Override + public String getPath() { + return this.path; + } + + public void setPath(String path) { + this.path = path; + } public VolumeObjectTO getVolume() { return volume; diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 3d7a901e352..fefb0ad3ec4 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -17,8 +17,6 @@ package org.apache.cloudstack.storage.to; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; -import org.apache.cloudstack.storage.image.datastore.ImageStoreInfo; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; @@ -27,17 +25,17 @@ import com.cloud.storage.Storage.ImageFormat; import com.cloud.template.VirtualMachineTemplate; public class TemplateObjectTO implements DataTO { - private String path; + private String path; private String origUrl; - private String uuid; + private String uuid; private long id; private ImageFormat format; private long accountId; private String checksum; private boolean hvm; private String displayText; - private DataStoreTO imageDataStore; - private String name; + private DataStoreTO imageDataStore; + private String name; private String guestOsType; private Long size; @@ -45,7 +43,7 @@ public class TemplateObjectTO implements DataTO { } - public TemplateObjectTO(VirtualMachineTemplate template){ + public TemplateObjectTO(VirtualMachineTemplate template) { this.uuid = template.getUuid(); this.id = template.getId(); this.origUrl = template.getUrl(); @@ -69,7 +67,7 @@ public class TemplateObjectTO implements DataTO { this.name = template.getUniqueName(); this.format = template.getFormat(); if (template.getDataStore() != null) { - this.imageDataStore = template.getDataStore().getTO(); + this.imageDataStore = template.getDataStore().getTO(); } } @@ -85,28 +83,35 @@ public class TemplateObjectTO implements DataTO { public long getId() { return id; } + public ImageFormat getFormat() { return format; } + public long getAccountId() { return accountId; } + public String getChecksum() { return checksum; } + public boolean isRequiresHvm() { return hvm; } - public void setRequiresHvm(boolean hvm){ + + public void setRequiresHvm(boolean hvm) { this.hvm = hvm; } + public String getDescription() { return displayText; } - public void setDescription(String desc){ + public void setDescription(String desc) { this.displayText = desc; } + public DataStoreTO getImageDataStore() { return this.imageDataStore; } @@ -118,7 +123,7 @@ public class TemplateObjectTO implements DataTO { @Override public DataStoreTO getDataStore() { - return (DataStoreTO)this.imageDataStore; + return (DataStoreTO) this.imageDataStore; } /** @@ -127,30 +132,39 @@ public class TemplateObjectTO implements DataTO { public String getName() { return name; } + public void setPath(String path) { this.path = path; } + public void setUuid(String uuid) { this.uuid = uuid; } + public void setName(String name) { this.name = name; } - public String getOrigUrl() { - return origUrl; - } - public void setOrigUrl(String origUrl) { - this.origUrl = origUrl; - } + + public String getOrigUrl() { + return origUrl; + } + + public void setOrigUrl(String origUrl) { + this.origUrl = origUrl; + } + public void setFormat(ImageFormat format) { this.format = format; } + public void setAccountId(long accountId) { this.accountId = accountId; } + public void setChecksum(String checksum) { this.checksum = checksum; } + public void setImageDataStore(DataStoreTO imageDataStore) { this.imageDataStore = imageDataStore; } @@ -163,11 +177,11 @@ public class TemplateObjectTO implements DataTO { this.guestOsType = guestOsType; } - public Long getSize() { - return size; - } + public Long getSize() { + return size; + } - public void setSize(Long size) { - this.size = size; - } + public void setSize(Long size) { + this.size = size; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 96cfbc7bf2d..be268ffc677 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -72,7 +72,7 @@ public class VolumeObjectTO implements DataTO { public Volume.Type getVolumeType() { return this.volumeType; } - + public DataStoreTO getDataStore() { return this.dataStore; } @@ -133,29 +133,28 @@ public class VolumeObjectTO implements DataTO { this.vmName = vmName; } - public String getChainInfo() { - return chainInfo; - } + public String getChainInfo() { + return chainInfo; + } - public void setChainInfo(String chainInfo) { - this.chainInfo = chainInfo; - } + public void setChainInfo(String chainInfo) { + this.chainInfo = chainInfo; + } - public long getId() { - return id; - } + public long getId() { + return id; + } - public void setId(long id) { - this.id = id; - } + public void setId(long id) { + this.id = id; + } - public Storage.ImageFormat getFormat() { - return format; - } - - public void setFormat(Storage.ImageFormat format) { - this.format = format; - } + public Storage.ImageFormat getFormat() { + return format; + } + public void setFormat(Storage.ImageFormat format) { + this.format = format; + } } diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java index 909d7fe6325..23b8d60e31c 100755 --- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java +++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java @@ -34,80 +34,78 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient; -import org.apache.cloudstack.api.Identity; import com.cloud.offering.DiskOffering; import com.cloud.utils.db.GenericDao; -import org.apache.cloudstack.api.InternalIdentity; @Entity -@Table(name="disk_offering") -@Inheritance(strategy=InheritanceType.JOINED) -@DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING, length=32) +@Table(name = "disk_offering") +@Inheritance(strategy = InheritanceType.JOINED) +@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING, length = 32) public class DiskOfferingVO implements DiskOffering { public enum Type { - Disk, - Service + Disk, Service }; @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") long id; - @Column(name="domain_id") + @Column(name = "domain_id") Long domainId; - @Column(name="unique_name") + @Column(name = "unique_name") private String uniqueName; - @Column(name="name") + @Column(name = "name") private String name = null; - @Column(name="display_text", length=4096) + @Column(name = "display_text", length = 4096) private String displayText = null; - @Column(name="disk_size") + @Column(name = "disk_size") long diskSize; - @Column(name="tags", length=4096) + @Column(name = "tags", length = 4096) String tags; - @Column(name="type") + @Column(name = "type") Type type; - @Column(name=GenericDao.REMOVED) + @Column(name = GenericDao.REMOVED) @Temporal(TemporalType.TIMESTAMP) private Date removed; - @Column(name=GenericDao.CREATED_COLUMN) + @Column(name = GenericDao.CREATED_COLUMN) private Date created; - @Column(name="recreatable") + @Column(name = "recreatable") private boolean recreatable; - @Column(name="use_local_storage") + @Column(name = "use_local_storage") private boolean useLocalStorage; - @Column(name="system_use") + @Column(name = "system_use") private boolean systemUse; - @Column(name="customized") + @Column(name = "customized") private boolean customized; - @Column(name="uuid") + @Column(name = "uuid") private String uuid; - @Column(name="sort_key") + @Column(name = "sort_key") int sortKey; - @Column(name="display_offering") + @Column(name = "display_offering") boolean displayOffering; public DiskOfferingVO() { - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } - public DiskOfferingVO(Long domainId, String name, String displayText, long diskSize, String tags, boolean isCustomized) { + public DiskOfferingVO(Long domainId, String name, String displayText, long diskSize, String tags, + boolean isCustomized) { this.domainId = domainId; this.name = name; this.displayText = displayText; @@ -117,10 +115,11 @@ public class DiskOfferingVO implements DiskOffering { this.type = Type.Disk; this.useLocalStorage = false; this.customized = isCustomized; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } - public DiskOfferingVO(String name, String displayText, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage, boolean systemUse, boolean customized) { + public DiskOfferingVO(String name, String displayText, boolean mirrored, String tags, boolean recreatable, + boolean useLocalStorage, boolean systemUse, boolean customized) { this.domainId = null; this.type = Type.Service; this.name = name; @@ -130,11 +129,13 @@ public class DiskOfferingVO implements DiskOffering { this.useLocalStorage = useLocalStorage; this.systemUse = systemUse; this.customized = customized; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } - //domain specific offerings constructor (null domainId implies public offering) - public DiskOfferingVO(String name, String displayText, boolean mirrored, String tags, boolean recreatable, boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) { + // domain specific offerings constructor (null domainId implies public + // offering) + public DiskOfferingVO(String name, String displayText, boolean mirrored, String tags, boolean recreatable, + boolean useLocalStorage, boolean systemUse, boolean customized, Long domainId) { this.type = Type.Service; this.name = name; this.displayText = displayText; @@ -144,7 +145,7 @@ public class DiskOfferingVO implements DiskOffering { this.systemUse = systemUse; this.customized = customized; this.domainId = domainId; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } @Override @@ -154,14 +155,14 @@ public class DiskOfferingVO implements DiskOffering { @Override public boolean isCustomized() { - return customized; - } + return customized; + } - public void setCustomized(boolean customized) { - this.customized = customized; - } + public void setCustomized(boolean customized) { + this.customized = customized; + } - @Override + @Override public String getUniqueName() { return uniqueName; } @@ -197,7 +198,6 @@ public class DiskOfferingVO implements DiskOffering { this.name = name; } - @Override public boolean getSystemUse() { return systemUse; @@ -211,13 +211,14 @@ public class DiskOfferingVO implements DiskOffering { public String getDisplayText() { return displayText; } + public void setDisplayText(String displayText) { this.displayText = displayText; } @Override - public long getDiskSize(){ - return diskSize; + public long getDiskSize() { + return diskSize; } @Override @@ -229,10 +230,10 @@ public class DiskOfferingVO implements DiskOffering { return removed; } - @Override + @Override public Date getCreated() { - return created; - } + return created; + } protected void setTags(String tags) { this.tags = tags; @@ -290,9 +291,9 @@ public class DiskOfferingVO implements DiskOffering { setTags(buf.toString()); } - public void setUseLocalStorage(boolean useLocalStorage) { - this.useLocalStorage = useLocalStorage; - } + public void setUseLocalStorage(boolean useLocalStorage) { + this.useLocalStorage = useLocalStorage; + } public void setRemoved(Date removed) { this.removed = removed; @@ -300,25 +301,24 @@ public class DiskOfferingVO implements DiskOffering { @Override public String getUuid() { - return this.uuid; + return this.uuid; } public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; } public void setSortKey(int key) { - sortKey = key; + sortKey = key; } public int getSortKey() { - return sortKey; - } - - public void setRecreatable(boolean recreatable) { - this.recreatable = recreatable; + return sortKey; } + public void setRecreatable(boolean recreatable) { + this.recreatable = recreatable; + } public boolean getDisplayOffering() { return displayOffering; diff --git a/engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java b/engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java index 03a74793001..36773e351e3 100644 --- a/engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java +++ b/engine/schema/src/com/cloud/storage/GuestOSCategoryVO.java @@ -25,44 +25,41 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; - @Entity -@Table(name="guest_os_category") +@Table(name = "guest_os_category") public class GuestOSCategoryVO implements GuestOsCategory { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") long id; - @Column(name="name") + @Column(name = "name") String name; - @Column(name="uuid") + @Column(name = "uuid") String uuid = UUID.randomUUID().toString(); @Override public long getId() { - return id; + return id; } @Override public String getName() { - return name; + return name; } @Override public void setName(String name) { - this.name = name; + this.name = name; } @Override public String getUuid() { - return this.uuid; + return this.uuid; } public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; } } diff --git a/engine/schema/src/com/cloud/storage/GuestOSVO.java b/engine/schema/src/com/cloud/storage/GuestOSVO.java index 49e136d03c1..f34d831d7a5 100644 --- a/engine/schema/src/com/cloud/storage/GuestOSVO.java +++ b/engine/schema/src/com/cloud/storage/GuestOSVO.java @@ -25,66 +25,63 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; - @Entity -@Table(name="guest_os") +@Table(name = "guest_os") public class GuestOSVO implements GuestOS { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") long id; - @Column(name="category_id") + @Column(name = "category_id") private long categoryId; - @Column(name="name") + @Column(name = "name") String name; - @Column(name="display_name") + @Column(name = "display_name") String displayName; - @Column(name="uuid") + @Column(name = "uuid") String uuid = UUID.randomUUID().toString(); @Override public long getId() { - return id; + return id; } public long getCategoryId() { - return categoryId; + return categoryId; } public void setCategoryId(long categoryId) { - this.categoryId = categoryId; + this.categoryId = categoryId; } @Override public String getName() { - return name; + return name; } public void setName(String name) { - this.name = name; + this.name = name; } @Override public String getDisplayName() { - return displayName; + return displayName; } public void setDisplayName(String displayName) { - this.displayName = displayName; + this.displayName = displayName; } @Override public String getUuid() { - return this.uuid; + return this.uuid; } public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; } } diff --git a/engine/schema/src/com/cloud/storage/LaunchPermissionVO.java b/engine/schema/src/com/cloud/storage/LaunchPermissionVO.java index 992bac2365e..9082debbd51 100644 --- a/engine/schema/src/com/cloud/storage/LaunchPermissionVO.java +++ b/engine/schema/src/com/cloud/storage/LaunchPermissionVO.java @@ -24,19 +24,20 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="launch_permission") +@Table(name = "launch_permission") public class LaunchPermissionVO implements InternalIdentity { @Id - @Column(name="id") + @Column(name = "id") private Long id; - @Column(name="template_id") + @Column(name = "template_id") private long templateId; - @Column(name="account_id") + @Column(name = "account_id") private long accountId; - public LaunchPermissionVO() { } + public LaunchPermissionVO() { + } public LaunchPermissionVO(long templateId, long accountId) { this.templateId = templateId; diff --git a/engine/schema/src/com/cloud/storage/S3VO.java b/engine/schema/src/com/cloud/storage/S3VO.java index ec49bc92d74..6b2c23fc1ae 100644 --- a/engine/schema/src/com/cloud/storage/S3VO.java +++ b/engine/schema/src/com/cloud/storage/S3VO.java @@ -18,10 +18,7 @@ */ package com.cloud.storage; -import com.cloud.agent.api.to.S3TO; -import com.cloud.utils.db.GenericDao; -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; +import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; @@ -29,7 +26,9 @@ import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import java.util.Date; + +import com.cloud.agent.api.to.S3TO; +import com.cloud.utils.db.GenericDao; @Entity @Table(name = "s3") @@ -76,11 +75,9 @@ public class S3VO implements S3 { super(); } - public S3VO(final String uuid, final String accessKey, - final String secretKey, final String endPoint, - final String bucketName, final Boolean httpsFlag, - final Integer connectionTimeout, final Integer maxErrorRetry, - final Integer socketTimeout, final Date created) { + public S3VO(final String uuid, final String accessKey, final String secretKey, final String endPoint, + final String bucketName, final Boolean httpsFlag, final Integer connectionTimeout, + final Integer maxErrorRetry, final Integer socketTimeout, final Date created) { super(); @@ -111,10 +108,8 @@ public class S3VO implements S3 { httpsFlag = this.httpsFlag == 0 ? false : true; } - return new S3TO(this.id, this.uuid, this.accessKey, this.secretKey, - this.endPoint, this.bucketName, httpsFlag, - this.connectionTimeout, this.maxErrorRetry, this.socketTimeout, - this.created); + return new S3TO(this.id, this.uuid, this.accessKey, this.secretKey, this.endPoint, this.bucketName, httpsFlag, + this.connectionTimeout, this.maxErrorRetry, this.socketTimeout, this.created); } diff --git a/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java b/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java index 4eb4916afd3..fc6283d177f 100644 --- a/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java +++ b/engine/schema/src/com/cloud/storage/SnapshotPolicyVO.java @@ -25,53 +25,51 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.api.Identity; import com.cloud.storage.snapshot.SnapshotPolicy; import com.cloud.utils.DateUtil.IntervalType; -import org.apache.cloudstack.api.InternalIdentity; @Entity -@Table(name="snapshot_policy") +@Table(name = "snapshot_policy") public class SnapshotPolicyVO implements SnapshotPolicy { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") long id; - @Column(name="volume_id") + @Column(name = "volume_id") long volumeId; - @Column(name="schedule") + @Column(name = "schedule") String schedule; - @Column(name="timezone") + @Column(name = "timezone") String timezone; - @Column(name="interval") + @Column(name = "interval") private short interval; - @Column(name="max_snaps") + @Column(name = "max_snaps") private int maxSnaps; - @Column(name="active") + @Column(name = "active") boolean active = false; - @Column(name="uuid") + @Column(name = "uuid") String uuid; public SnapshotPolicyVO() { - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } public SnapshotPolicyVO(long volumeId, String schedule, String timezone, IntervalType intvType, int maxSnaps) { - this.volumeId = volumeId; + this.volumeId = volumeId; this.schedule = schedule; this.timezone = timezone; - this.interval = (short)intvType.ordinal(); + this.interval = (short) intvType.ordinal(); this.maxSnaps = maxSnaps; this.active = true; - this.uuid = UUID.randomUUID().toString(); + this.uuid = UUID.randomUUID().toString(); } public long getId() { @@ -79,10 +77,10 @@ public class SnapshotPolicyVO implements SnapshotPolicy { } public long getVolumeId() { - return volumeId; - } + return volumeId; + } - public void setSchedule(String schedule) { + public void setSchedule(String schedule) { this.schedule = schedule; } @@ -124,10 +122,10 @@ public class SnapshotPolicyVO implements SnapshotPolicy { @Override public String getUuid() { - return this.uuid; + return this.uuid; } public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; } } diff --git a/engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java b/engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java index 75757c6b22b..7adc136066f 100644 --- a/engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java +++ b/engine/schema/src/com/cloud/storage/SnapshotScheduleVO.java @@ -28,40 +28,40 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.api.Identity; import com.cloud.storage.snapshot.SnapshotSchedule; -import org.apache.cloudstack.api.InternalIdentity; @Entity -@Table(name="snapshot_schedule") +@Table(name = "snapshot_schedule") public class SnapshotScheduleVO implements SnapshotSchedule { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") - long id; + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + long id; - // DB constraint: For a given volume and policyId, there will only be one entry in this table. - @Column(name="volume_id") + // DB constraint: For a given volume and policyId, there will only be one + // entry in this table. + @Column(name = "volume_id") long volumeId; - @Column(name="policy_id") + @Column(name = "policy_id") long policyId; - @Column(name="scheduled_timestamp") - @Temporal(value=TemporalType.TIMESTAMP) + @Column(name = "scheduled_timestamp") + @Temporal(value = TemporalType.TIMESTAMP) Date scheduledTimestamp; - @Column(name="async_job_id") + @Column(name = "async_job_id") Long asyncJobId; - @Column(name="snapshot_id") + @Column(name = "snapshot_id") Long snapshotId; - @Column(name="uuid") + @Column(name = "uuid") String uuid = UUID.randomUUID().toString(); - public SnapshotScheduleVO() { } + public SnapshotScheduleVO() { + } public SnapshotScheduleVO(long volumeId, long policyId, Date scheduledTimestamp) { this.volumeId = volumeId; @@ -83,43 +83,43 @@ public class SnapshotScheduleVO implements SnapshotSchedule { return policyId; } - public void setPolicyId(long policyId) { + public void setPolicyId(long policyId) { this.policyId = policyId; } /** - * @return the scheduledTimestamp - */ - public Date getScheduledTimestamp() { - return scheduledTimestamp; - } + * @return the scheduledTimestamp + */ + public Date getScheduledTimestamp() { + return scheduledTimestamp; + } - public void setScheduledTimestamp(Date scheduledTimestamp) { + public void setScheduledTimestamp(Date scheduledTimestamp) { this.scheduledTimestamp = scheduledTimestamp; } public Long getAsyncJobId() { - return asyncJobId; - } + return asyncJobId; + } - public void setAsyncJobId(Long asyncJobId) { - this.asyncJobId = asyncJobId; - } + public void setAsyncJobId(Long asyncJobId) { + this.asyncJobId = asyncJobId; + } - public Long getSnapshotId() { - return snapshotId; - } + public Long getSnapshotId() { + return snapshotId; + } - public void setSnapshotId(Long snapshotId) { - this.snapshotId = snapshotId; - } + public void setSnapshotId(Long snapshotId) { + this.snapshotId = snapshotId; + } - @Override - public String getUuid() { - return this.uuid; - } + @Override + public String getUuid() { + return this.uuid; + } - public void setUuid(String uuid) { - this.uuid = uuid; - } + public void setUuid(String uuid) { + this.uuid = uuid; + } } diff --git a/engine/schema/src/com/cloud/storage/SnapshotVO.java b/engine/schema/src/com/cloud/storage/SnapshotVO.java index 4fc195cfec4..e3912740a48 100644 --- a/engine/schema/src/com/cloud/storage/SnapshotVO.java +++ b/engine/schema/src/com/cloud/storage/SnapshotVO.java @@ -25,69 +25,70 @@ import java.util.Date; import java.util.UUID; @Entity -@Table(name="snapshots") +@Table(name = "snapshots") public class SnapshotVO implements Snapshot { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private long id; - @Column(name="data_center_id") + @Column(name = "data_center_id") long dataCenterId; - @Column(name="account_id") + @Column(name = "account_id") long accountId; - @Column(name="domain_id") + @Column(name = "domain_id") long domainId; - @Column(name="volume_id") + @Column(name = "volume_id") Long volumeId; - @Column(name="disk_offering_id") + @Column(name = "disk_offering_id") Long diskOfferingId; @Expose - @Column(name="name") + @Column(name = "name") String name; @Expose - @Column(name="status", updatable = true, nullable=false) - @Enumerated(value=EnumType.STRING) + @Column(name = "status", updatable = true, nullable = false) + @Enumerated(value = EnumType.STRING) private State state; - @Column(name="snapshot_type") + @Column(name = "snapshot_type") short snapshotType; - @Column(name="type_description") + @Column(name = "type_description") String typeDescription; - @Column(name="size") + @Column(name = "size") long size; - @Column(name=GenericDao.CREATED_COLUMN) + @Column(name = GenericDao.CREATED_COLUMN) Date created; - @Column(name=GenericDao.REMOVED_COLUMN) + @Column(name = GenericDao.REMOVED_COLUMN) Date removed; - @Column(name="hypervisor_type") - @Enumerated(value=EnumType.STRING) - HypervisorType hypervisorType; + @Column(name = "hypervisor_type") + @Enumerated(value = EnumType.STRING) + HypervisorType hypervisorType; @Expose - @Column(name="version") + @Column(name = "version") String version; - @Column(name="uuid") + @Column(name = "uuid") String uuid; public SnapshotVO() { this.uuid = UUID.randomUUID().toString(); } - public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType ) { + public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String name, + short snapshotType, String typeDescription, long size, HypervisorType hypervisorType) { this.dataCenterId = dcId; this.accountId = accountId; this.domainId = domainId; @@ -135,11 +136,11 @@ public class SnapshotVO implements Snapshot { this.volumeId = volumeId; } - @Override public String getName() { return name; } + @Override public short getsnapshotType() { return snapshotType; @@ -163,8 +164,8 @@ public class SnapshotVO implements Snapshot { } @Override - public boolean isRecursive(){ - if ( snapshotType >= Type.HOURLY.ordinal() && snapshotType <= Type.MONTHLY.ordinal() ) { + public boolean isRecursive() { + if (snapshotType >= Type.HOURLY.ordinal() && snapshotType <= Type.MONTHLY.ordinal()) { return true; } return false; @@ -177,6 +178,7 @@ public class SnapshotVO implements Snapshot { public String getTypeDescription() { return typeDescription; } + public void setTypeDescription(String typeDescription) { this.typeDescription = typeDescription; } @@ -203,14 +205,13 @@ public class SnapshotVO implements Snapshot { return state; } - - public void setState(State state) { + public void setState(State state) { this.state = state; } public static Type getSnapshotType(String snapshotType) { - for ( Type type : Type.values()) { - if ( type.equals(snapshotType)) { + for (Type type : Type.values()) { + if (type.equals(snapshotType)) { return type; } } diff --git a/engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java b/engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java index 34326d963a6..1b20bf62c66 100644 --- a/engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java +++ b/engine/schema/src/com/cloud/storage/StoragePoolHostAssoc.java @@ -21,15 +21,15 @@ import org.apache.cloudstack.api.InternalIdentity; import java.util.Date; public interface StoragePoolHostAssoc extends InternalIdentity { - - long getHostId(); - - long getPoolId(); - - String getLocalPath(); - Date getCreated(); + long getHostId(); - Date getLastUpdated(); + long getPoolId(); + + String getLocalPath(); + + Date getCreated(); + + Date getLastUpdated(); } diff --git a/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java b/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java index 1b02f6d9754..3b70984e63c 100644 --- a/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java +++ b/engine/schema/src/com/cloud/storage/StoragePoolHostVO.java @@ -31,79 +31,73 @@ import com.cloud.utils.db.GenericDaoBase; /** * Join table for storage pools and hosts - * + * */ @Entity -@Table(name="storage_pool_host_ref") +@Table(name = "storage_pool_host_ref") public class StoragePoolHostVO implements StoragePoolHostAssoc { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - private Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; - @Column(name="pool_id") - private long poolId; + @Column(name = "pool_id") + private long poolId; - @Column(name="host_id") - private long hostId; + @Column(name = "host_id") + private long hostId; - @Column(name="local_path") - private String localPath; + @Column(name = "local_path") + private String localPath; - @Column(name=GenericDaoBase.CREATED_COLUMN) + @Column(name = GenericDaoBase.CREATED_COLUMN) private Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) private Date lastUpdated = null; + public StoragePoolHostVO() { + super(); + } - public StoragePoolHostVO() { - super(); - } - - - public StoragePoolHostVO(long poolId, long hostId, String localPath) { - this.poolId = poolId; - this.hostId = hostId; - this.localPath = localPath; - } - - - @Override - public long getHostId() { - return hostId; - } + public StoragePoolHostVO(long poolId, long hostId, String localPath) { + this.poolId = poolId; + this.hostId = hostId; + this.localPath = localPath; + } + @Override + public long getHostId() { + return hostId; + } @Override public long getId() { return id; } + @Override + public String getLocalPath() { + return localPath; + } @Override - public String getLocalPath() { - return localPath; - } + public long getPoolId() { + return poolId; + } - @Override - public long getPoolId() { - return poolId; - } + @Override + public Date getCreated() { + return created; + } - @Override - public Date getCreated() { - return created; - } + @Override + public Date getLastUpdated() { + return lastUpdated; + } - @Override - public Date getLastUpdated() { - return lastUpdated; - } - - - public void setLocalPath(String localPath) { - this.localPath = localPath; - } + public void setLocalPath(String localPath) { + this.localPath = localPath; + } } diff --git a/engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java b/engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java index 440065da66b..56d57ec1e33 100644 --- a/engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java +++ b/engine/schema/src/com/cloud/storage/StoragePoolWorkVO.java @@ -27,9 +27,9 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="storage_pool_work") +@Table(name = "storage_pool_work") public class StoragePoolWorkVO implements InternalIdentity { - + public long getId() { return id; } @@ -42,22 +42,18 @@ public class StoragePoolWorkVO implements InternalIdentity { return poolId; } - public void setPoolId(Long poolId) { this.poolId = poolId; } - public boolean isStoppedForMaintenance() { return stoppedForMaintenance; } - public void setStoppedForMaintenance(boolean stoppedForMaintenance) { this.stoppedForMaintenance = stoppedForMaintenance; } - public boolean isStartedAfterMaintenance() { return startedAfterMaintenance; } @@ -73,7 +69,7 @@ public class StoragePoolWorkVO implements InternalIdentity { public void setVmId(Long vmId) { this.vmId = vmId; } - + public Long getManagementServerId() { return managementServerId; } @@ -83,27 +79,27 @@ public class StoragePoolWorkVO implements InternalIdentity { } @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private Long id; - - @Column(name="pool_id") + + @Column(name = "pool_id") private Long poolId; - @Column(name="vm_id") + @Column(name = "vm_id") private Long vmId; - - @Column(name="stopped_for_maintenance") + + @Column(name = "stopped_for_maintenance") private boolean stoppedForMaintenance; - - @Column(name="started_after_maintenance") + + @Column(name = "started_after_maintenance") private boolean startedAfterMaintenance; - @Column(name="mgmt_server_id") + @Column(name = "mgmt_server_id") private Long managementServerId; - - public StoragePoolWorkVO(long vmId, long poolId, boolean stoppedForMaintenance, boolean startedAfterMaintenance, long mgmtServerId) { + public StoragePoolWorkVO(long vmId, long poolId, boolean stoppedForMaintenance, boolean startedAfterMaintenance, + long mgmtServerId) { super(); this.vmId = vmId; this.poolId = poolId; @@ -111,8 +107,8 @@ public class StoragePoolWorkVO implements InternalIdentity { this.startedAfterMaintenance = startedAfterMaintenance; this.managementServerId = mgmtServerId; } - + public StoragePoolWorkVO() { - + } } diff --git a/engine/schema/src/com/cloud/storage/SwiftVO.java b/engine/schema/src/com/cloud/storage/SwiftVO.java index c99f0efc702..4136a224b3c 100644 --- a/engine/schema/src/com/cloud/storage/SwiftVO.java +++ b/engine/schema/src/com/cloud/storage/SwiftVO.java @@ -26,39 +26,40 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import com.cloud.agent.api.to.SwiftTO; -import org.apache.cloudstack.api.Identity; -import com.cloud.utils.db.GenericDao; import org.apache.cloudstack.api.InternalIdentity; +import com.cloud.agent.api.to.SwiftTO; +import com.cloud.utils.db.GenericDao; + @Entity -@Table(name="swift") +@Table(name = "swift") public class SwiftVO implements Swift, InternalIdentity { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private long id; - @Column(name="url") + @Column(name = "url") String url; - @Column(name="account") + @Column(name = "account") String account; - @Column(name="username") + @Column(name = "username") String userName; - @Column(name="key") + @Column(name = "key") String key; - @Column(name="uuid") + @Column(name = "uuid") String uuid = UUID.randomUUID().toString(); @Column(name = GenericDao.CREATED_COLUMN) private Date created; - public SwiftVO() { } + public SwiftVO() { + } public SwiftVO(String url, String account, String userName, String key) { this.url = url; @@ -71,18 +72,22 @@ public class SwiftVO implements Swift, InternalIdentity { public long getId() { return id; } + @Override public String getUrl() { return url; } + @Override public String getAccount() { return account; } + @Override public String getUserName() { return userName; } + @Override public String getKey() { return key; @@ -99,10 +104,10 @@ public class SwiftVO implements Swift, InternalIdentity { @Override public String getUuid() { - return this.uuid; + return this.uuid; } public void setUuid(String uuid) { - this.uuid = uuid; + this.uuid = uuid; } } diff --git a/engine/schema/src/com/cloud/storage/UploadVO.java b/engine/schema/src/com/cloud/storage/UploadVO.java index fe8b81280fd..63fadfac3e8 100755 --- a/engine/schema/src/com/cloud/storage/UploadVO.java +++ b/engine/schema/src/com/cloud/storage/UploadVO.java @@ -34,112 +34,109 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.GenericDaoBase; @Entity -@Table(name="upload") +@Table(name = "upload") public class UploadVO implements Upload { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + long id; - @Column(name="uuid") - private String uuid; + @Column(name = "uuid") + private String uuid; - @Column(name="host_id") - private long storeId; + @Column(name = "host_id") + private long storeId; - @Column(name="type_id") - private long typeId; + @Column(name = "type_id") + private long typeId; - @Column(name=GenericDaoBase.CREATED_COLUMN) - private Date created = null; + @Column(name = GenericDaoBase.CREATED_COLUMN) + private Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) - private Date lastUpdated = null; + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) + private Date lastUpdated = null; - @Column (name="upload_pct") - private int uploadPercent; + @Column(name = "upload_pct") + private int uploadPercent; - @Column (name="type") - @Enumerated(EnumType.STRING) - private Type type; + @Column(name = "type") + @Enumerated(EnumType.STRING) + private Type type; - @Column (name="mode") + @Column(name = "mode") @Enumerated(EnumType.STRING) private Mode mode = Mode.FTP_UPLOAD; - @Column (name="upload_state") - @Enumerated(EnumType.STRING) - private Status uploadState; + @Column(name = "upload_state") + @Enumerated(EnumType.STRING) + private Status uploadState; - @Column (name="error_str") - private String errorString; + @Column(name = "error_str") + private String errorString; - @Column (name="job_id") - private String jobId; + @Column(name = "job_id") + private String jobId; - @Column (name="url") - private String uploadUrl; + @Column(name = "url") + private String uploadUrl; - @Column (name="install_path") - private String installPath; + @Column(name = "install_path") + private String installPath; - @Override + @Override public long getDataStoreId() { - return storeId; - } + return storeId; + } - public void setDataStoreId(long hostId) { - this.storeId = hostId; - } + public void setDataStoreId(long hostId) { + this.storeId = hostId; + } - @Override + @Override public long getId() { - return id; - } + return id; + } - - @Override + @Override public String getUuid() { return uuid; } @Override public Date getCreated() { - return created; - } + return created; + } - @Override + @Override public Date getLastUpdated() { - return lastUpdated; - } + return lastUpdated; + } - public void setLastUpdated(Date date) { - lastUpdated = date; - } + public void setLastUpdated(Date date) { + lastUpdated = date; + } - public UploadVO(long hostId, long templateId) { - super(); - this.storeId = hostId; - this.typeId = templateId; - this.uuid = UUID.randomUUID().toString(); - } - - public UploadVO(long hostId, long typeId, Date lastUpdated, - Status uploadState, Type type, - String uploadUrl, Mode mode) { - super(); - this.storeId = hostId; - this.typeId = typeId; - this.lastUpdated = lastUpdated; - this.uploadState = uploadState; - this.mode = mode; - this.type = type; - this.uploadUrl = uploadUrl; + public UploadVO(long hostId, long templateId) { + super(); + this.storeId = hostId; + this.typeId = templateId; this.uuid = UUID.randomUUID().toString(); - } + } - public UploadVO(long hostId, long typeId, Date lastUpdated, - Status uploadState, int uploadPercent, Type type, + public UploadVO(long hostId, long typeId, Date lastUpdated, Status uploadState, Type type, String uploadUrl, + Mode mode) { + super(); + this.storeId = hostId; + this.typeId = typeId; + this.lastUpdated = lastUpdated; + this.uploadState = uploadState; + this.mode = mode; + this.type = type; + this.uploadUrl = uploadUrl; + this.uuid = UUID.randomUUID().toString(); + } + + public UploadVO(long hostId, long typeId, Date lastUpdated, Status uploadState, int uploadPercent, Type type, Mode mode) { super(); this.storeId = hostId; @@ -153,82 +150,83 @@ public class UploadVO implements Upload { } - protected UploadVO() { - } + protected UploadVO() { + } - public UploadVO(Long uploadId) { - this.id = uploadId; - } + public UploadVO(Long uploadId) { + this.id = uploadId; + } - public void setErrorString(String errorString) { - this.errorString = errorString; - } + public void setErrorString(String errorString) { + this.errorString = errorString; + } - @Override + @Override public String getErrorString() { - return errorString; - } + return errorString; + } - public void setJobId(String jobId) { - this.jobId = jobId; - } + public void setJobId(String jobId) { + this.jobId = jobId; + } - @Override + @Override public String getJobId() { - return jobId; - } + return jobId; + } - @Override - public boolean equals(Object obj) { - if (obj instanceof UploadVO) { - UploadVO other = (UploadVO)obj; - return (this.typeId==other.getTypeId() && this.storeId==other.getDataStoreId() && this.type == other.getType()); - } - return false; - } + @Override + public boolean equals(Object obj) { + if (obj instanceof UploadVO) { + UploadVO other = (UploadVO) obj; + return (this.typeId == other.getTypeId() && this.storeId == other.getDataStoreId() && this.type == other + .getType()); + } + return false; + } - @Override - public int hashCode() { - return NumbersUtil.hash(id); - } + @Override + public int hashCode() { + return NumbersUtil.hash(id); + } - @Override + @Override public int getUploadPercent() { - return uploadPercent; - } + return uploadPercent; + } - public void setUploadPercent(int uploadPercent) { - this.uploadPercent = uploadPercent; - } + public void setUploadPercent(int uploadPercent) { + this.uploadPercent = uploadPercent; + } - @Override + @Override public Status getUploadState() { - return uploadState; - } + return uploadState; + } - public void setUploadState(Status uploadState) { - this.uploadState = uploadState; - } + public void setUploadState(Status uploadState) { + this.uploadState = uploadState; + } - @Override + @Override public long getTypeId() { - return typeId; - } + return typeId; + } - public void setTypeId(long typeId) { - this.typeId = typeId; - } + public void setTypeId(long typeId) { + this.typeId = typeId; + } - @Override + @Override public Type getType() { - return type; - } + return type; + } - public void setType(Type type) { - this.type = type; - } + public void setType(Type type) { + this.type = type; + } - @Override + @Override public Mode getMode() { return mode; } @@ -239,22 +237,22 @@ public class UploadVO implements Upload { @Override public String getUploadUrl() { - return uploadUrl; - } + return uploadUrl; + } - public void setUploadUrl(String uploadUrl) { - this.uploadUrl = uploadUrl; - } + public void setUploadUrl(String uploadUrl) { + this.uploadUrl = uploadUrl; + } - @Override + @Override public void setId(Long id) { - this.id = id; - } + this.id = id; + } - @Override + @Override public void setCreated(Date created) { - this.created = created; - } + this.created = created; + } @Override public String getInstallPath() { diff --git a/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java b/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java index c007802db3f..3d4c7ef30db 100644 --- a/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateDetailVO.java @@ -26,59 +26,60 @@ import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="vm_template_details") +@Table(name = "vm_template_details") public class VMTemplateDetailVO implements InternalIdentity { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private long id; - - @Column(name="template_id") + + @Column(name = "template_id") private long templateId; - - @Column(name="name") + + @Column(name = "name") private String name; - - @Column(name="value", length=1024) + + @Column(name = "value", length = 1024) private String value; - - public VMTemplateDetailVO() {} - - public VMTemplateDetailVO(long templateId, String name, String value) { - this.templateId = templateId; - this.name = name; - this.value = value; + + public VMTemplateDetailVO() { } - public long getId() { - return id; - } + public VMTemplateDetailVO(long templateId, String name, String value) { + this.templateId = templateId; + this.name = name; + this.value = value; + } - public long getTemplateId() { - return templateId; - } + public long getId() { + return id; + } - public String getName() { - return name; - } + public long getTemplateId() { + return templateId; + } - public String getValue() { - return value; - } + public String getName() { + return name; + } - public void setId(long id) { - this.id = id; - } + public String getValue() { + return value; + } - public void setTemplateId(long templateId) { - this.templateId = templateId; - } + public void setId(long id) { + this.id = id; + } - public void setName(String name) { - this.name = name; - } + public void setTemplateId(long templateId) { + this.templateId = templateId; + } - public void setValue(String value) { - this.value = value; - } + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } } diff --git a/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java b/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java index 227394248b3..33732a419c9 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateHostVO.java @@ -37,63 +37,63 @@ import com.cloud.utils.db.GenericDaoBase; /** * Join table for storage hosts and templates - * + * */ @Entity -@Table(name="template_host_ref") +@Table(name = "template_host_ref") public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObjectInStore { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - Long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; - @Column(name="host_id") - private long hostId; + @Column(name = "host_id") + private long hostId; - @Column(name="template_id") - private long templateId; + @Column(name = "template_id") + private long templateId; - @Column(name=GenericDaoBase.CREATED_COLUMN) - private Date created = null; + @Column(name = GenericDaoBase.CREATED_COLUMN) + private Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) - private Date lastUpdated = null; + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) + private Date lastUpdated = null; - @Column (name="download_pct") - private int downloadPercent; + @Column(name = "download_pct") + private int downloadPercent; - @Column (name="size") - private long size; + @Column(name = "size") + private long size; - @Column (name="physical_size") - private long physicalSize; + @Column(name = "physical_size") + private long physicalSize; - @Column (name="download_state") - @Enumerated(EnumType.STRING) - private Status downloadState; + @Column(name = "download_state") + @Enumerated(EnumType.STRING) + private Status downloadState; - @Column (name="local_path") - private String localDownloadPath; + @Column(name = "local_path") + private String localDownloadPath; - @Column (name="error_str") - private String errorString; + @Column(name = "error_str") + private String errorString; - @Column (name="job_id") - private String jobId; + @Column(name = "job_id") + private String jobId; - @Column (name="install_path") + @Column(name = "install_path") private String installPath; - @Column (name="url") - private String downloadUrl; + @Column(name = "url") + private String downloadUrl; - @Column(name="is_copy") - private boolean isCopy = false; + @Column(name = "is_copy") + private boolean isCopy = false; - @Column(name="destroyed") + @Column(name = "destroyed") boolean destroyed = false; - @Column(name="update_count", updatable = true, nullable=false) + @Column(name = "update_count", updatable = true, nullable = false) protected long updatedCount; @Column(name = "updated") @@ -104,148 +104,145 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj @Enumerated(EnumType.STRING) ObjectInDataStoreStateMachine.State state; - - @Override + @Override public String getInstallPath() { - return installPath; - } + return installPath; + } - public long getHostId() { - return hostId; - } + public long getHostId() { + return hostId; + } - public void setHostId(long hostId) { - this.hostId = hostId; - } + public void setHostId(long hostId) { + this.hostId = hostId; + } - @Override + @Override public long getTemplateId() { - return templateId; - } + return templateId; + } - @Override + @Override public void setTemplateId(long templateId) { - this.templateId = templateId; - } + this.templateId = templateId; + } - @Override + @Override public int getDownloadPercent() { - return downloadPercent; - } + return downloadPercent; + } - @Override + @Override public void setDownloadPercent(int downloadPercent) { - this.downloadPercent = downloadPercent; - } + this.downloadPercent = downloadPercent; + } - @Override + @Override public void setDownloadState(Status downloadState) { - this.downloadState = downloadState; - } + this.downloadState = downloadState; + } - @Override + @Override public long getId() { - return id; - } + return id; + } - @Override + @Override public Date getCreated() { - return created; - } + return created; + } - @Override + @Override public Date getLastUpdated() { - return lastUpdated; - } + return lastUpdated; + } - @Override + @Override public void setLastUpdated(Date date) { - lastUpdated = date; - } + lastUpdated = date; + } - @Override + @Override public void setInstallPath(String installPath) { - this.installPath = installPath; - } + this.installPath = installPath; + } - @Override + @Override public Status getDownloadState() { - return downloadState; - } + return downloadState; + } - public VMTemplateHostVO(long hostId, long templateId) { - super(); - this.hostId = hostId; - this.templateId = templateId; - this.state = ObjectInDataStoreStateMachine.State.Allocated; - } + public VMTemplateHostVO(long hostId, long templateId) { + super(); + this.hostId = hostId; + this.templateId = templateId; + this.state = ObjectInDataStoreStateMachine.State.Allocated; + } - public VMTemplateHostVO(long hostId, long templateId, Date lastUpdated, - int downloadPercent, Status downloadState, - String localDownloadPath, String errorString, String jobId, - String installPath, String downloadUrl) { - super(); - this.hostId = hostId; - 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.setDownloadUrl(downloadUrl); - } + public VMTemplateHostVO(long hostId, long templateId, Date lastUpdated, int downloadPercent, Status downloadState, + String localDownloadPath, String errorString, String jobId, String installPath, String downloadUrl) { + super(); + this.hostId = hostId; + 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.setDownloadUrl(downloadUrl); + } - protected VMTemplateHostVO() { + protected VMTemplateHostVO() { - } + } - @Override + @Override public void setLocalDownloadPath(String localPath) { - this.localDownloadPath = localPath; - } + this.localDownloadPath = localPath; + } - @Override + @Override public String getLocalDownloadPath() { - return localDownloadPath; - } + return localDownloadPath; + } - @Override + @Override public void setErrorString(String errorString) { - this.errorString = errorString; - } + this.errorString = errorString; + } - @Override + @Override public String getErrorString() { - return errorString; - } + return errorString; + } - @Override + @Override public void setJobId(String jobId) { - this.jobId = jobId; - } + this.jobId = jobId; + } - @Override + @Override public String getJobId() { - return jobId; - } + return jobId; + } - @Override - public boolean equals(Object obj) { - if (obj instanceof VMTemplateHostVO) { - VMTemplateHostVO other = (VMTemplateHostVO)obj; - return (this.templateId==other.getTemplateId() && this.hostId==other.getHostId()); - } - return false; - } + @Override + public boolean equals(Object obj) { + if (obj instanceof VMTemplateHostVO) { + VMTemplateHostVO other = (VMTemplateHostVO) obj; + return (this.templateId == other.getTemplateId() && this.hostId == other.getHostId()); + } + return false; + } - @Override - public int hashCode() { - Long tid = new Long(templateId); - Long hid = new Long(hostId); - return tid.hashCode()+hid.hashCode(); - } + @Override + public int hashCode() { + Long tid = new Long(templateId); + Long hid = new Long(hostId); + return tid.hashCode() + hid.hashCode(); + } public void setSize(long size) { this.size = size; @@ -255,7 +252,6 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj return size; } - public void setPhysicalSize(long physicalSize) { this.physicalSize = physicalSize; } @@ -265,38 +261,39 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj } public void setDestroyed(boolean destroyed) { - this.destroyed = destroyed; + this.destroyed = destroyed; } public boolean getDestroyed() { - return destroyed; + return destroyed; } - public void setDownloadUrl(String downloadUrl) { - this.downloadUrl = downloadUrl; - } + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } - public String getDownloadUrl() { - return downloadUrl; - } + public String getDownloadUrl() { + return downloadUrl; + } - public void setCopy(boolean isCopy) { - this.isCopy = isCopy; - } + public void setCopy(boolean isCopy) { + this.isCopy = isCopy; + } - public boolean isCopy() { - return isCopy; - } + public boolean isCopy() { + return isCopy; + } - @Override + @Override public long getTemplateSize() { - return -1; - } + return -1; + } - @Override + @Override public String toString() { - return new StringBuilder("TmplHost[").append(id).append("-").append(templateId).append("-").append(hostId).append(installPath).append("]").toString(); - } + return new StringBuilder("TmplHost[").append(id).append("-").append(templateId).append("-").append(hostId) + .append(installPath).append("]").toString(); + } @Override public ObjectInDataStoreStateMachine.State getState() { @@ -335,5 +332,4 @@ public class VMTemplateHostVO implements VMTemplateStorageResourceAssoc, DataObj return this.state; } - } diff --git a/engine/schema/src/com/cloud/storage/VMTemplateS3VO.java b/engine/schema/src/com/cloud/storage/VMTemplateS3VO.java index 02f3ff5cf7f..e106bf7d1a5 100644 --- a/engine/schema/src/com/cloud/storage/VMTemplateS3VO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateS3VO.java @@ -62,8 +62,8 @@ public class VMTemplateS3VO implements InternalIdentity { super(); } - public VMTemplateS3VO(final long s3Id, final long templateId, - final Date created, final Long size, final Long physicalSize) { + public VMTemplateS3VO(final long s3Id, final long templateId, final Date created, final Long size, + final Long physicalSize) { super(); @@ -100,19 +100,16 @@ public class VMTemplateS3VO implements InternalIdentity { return false; } - if (this.created != null ? !created.equals(thatVMTemplateS3VO.created) - : thatVMTemplateS3VO.created != null) { + if (this.created != null ? !created.equals(thatVMTemplateS3VO.created) : thatVMTemplateS3VO.created != null) { return false; } - if (this.physicalSize != null ? !physicalSize - .equals(thatVMTemplateS3VO.physicalSize) + if (this.physicalSize != null ? !physicalSize.equals(thatVMTemplateS3VO.physicalSize) : thatVMTemplateS3VO.physicalSize != null) { return false; } - if (this.size != null ? !size.equals(thatVMTemplateS3VO.size) - : thatVMTemplateS3VO.size != null) { + if (this.size != null ? !size.equals(thatVMTemplateS3VO.size) : thatVMTemplateS3VO.size != null) { return false; } @@ -125,14 +122,10 @@ public class VMTemplateS3VO implements InternalIdentity { int result = (int) (this.id ^ (this.id >>> 32)); result = 31 * result + (int) (this.s3Id ^ (this.s3Id >>> 32)); - result = 31 * result - + (int) (this.templateId ^ (this.templateId >>> 32)); - result = 31 * result - + (this.created != null ? this.created.hashCode() : 0); + result = 31 * result + (int) (this.templateId ^ (this.templateId >>> 32)); + result = 31 * result + (this.created != null ? this.created.hashCode() : 0); result = 31 * result + (this.size != null ? this.size.hashCode() : 0); - result = 31 - * result - + (this.physicalSize != null ? this.physicalSize.hashCode() : 0); + result = 31 * result + (this.physicalSize != null ? this.physicalSize.hashCode() : 0); return result; @@ -189,13 +182,10 @@ public class VMTemplateS3VO implements InternalIdentity { @Override public String toString() { - final StringBuilder stringBuilder = new StringBuilder( - "VMTemplateS3VO [ id: ").append(id).append(", created: ") - .append(DateFormat.getDateTimeInstance().format(created)) - .append(", physicalSize: ").append(physicalSize) - .append(", size: ").append(size).append(", templateId: ") - .append(templateId).append(", s3Id: ").append(s3Id) - .append(" ]"); + final StringBuilder stringBuilder = new StringBuilder("VMTemplateS3VO [ id: ").append(id).append(", created: ") + .append(DateFormat.getDateTimeInstance().format(created)).append(", physicalSize: ") + .append(physicalSize).append(", size: ").append(size).append(", templateId: ").append(templateId) + .append(", s3Id: ").append(s3Id).append(" ]"); return stringBuilder.toString(); diff --git a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java index 4c6a758ca90..10ced67244f 100644 --- a/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateStoragePoolVO.java @@ -37,218 +37,229 @@ import com.cloud.utils.db.GenericDaoBase; /** * Join table for storage pools and templates - * + * */ @Entity -@Table(name="template_spool_ref") +@Table(name = "template_spool_ref") public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, DataObjectInStore { - @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - long id; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + long id; - @Column(name="pool_id") - private long poolId; + @Column(name = "pool_id") + private long poolId; - @Column(name="template_id") long templateId; + @Column(name = "template_id") + long templateId; - @Column(name=GenericDaoBase.CREATED_COLUMN) Date created = null; + @Column(name = GenericDaoBase.CREATED_COLUMN) + Date created = null; - @Column(name="last_updated") - @Temporal(value=TemporalType.TIMESTAMP) Date lastUpdated = null; + @Column(name = "last_updated") + @Temporal(value = TemporalType.TIMESTAMP) + Date lastUpdated = null; - @Column (name="download_pct") int downloadPercent; + @Column(name = "download_pct") + int downloadPercent; - @Column (name="download_state") - @Enumerated(EnumType.STRING) Status downloadState; + @Column(name = "download_state") + @Enumerated(EnumType.STRING) + Status downloadState; - @Column (name="local_path") String localDownloadPath; + @Column(name = "local_path") + String localDownloadPath; - @Column (name="error_str") String errorString; + @Column(name = "error_str") + String errorString; - @Column (name="job_id") String jobId; + @Column(name = "job_id") + String jobId; - @Column (name="install_path") String installPath; + @Column(name = "install_path") + String installPath; - @Column (name="template_size") long templateSize; + @Column(name = "template_size") + long templateSize; - @Column (name="marked_for_gc") boolean markedForGC; + @Column(name = "marked_for_gc") + boolean markedForGC; - @Column(name="update_count", updatable = true, nullable=false) - protected long updatedCount; + @Column(name = "update_count", updatable = true, nullable = false) + protected long updatedCount; - @Column(name = "updated") - @Temporal(value = TemporalType.TIMESTAMP) - Date updated; + @Column(name = "updated") + @Temporal(value = TemporalType.TIMESTAMP) + Date updated; - @Column(name = "state") - @Enumerated(EnumType.STRING) - ObjectInDataStoreStateMachine.State state; + @Column(name = "state") + @Enumerated(EnumType.STRING) + ObjectInDataStoreStateMachine.State state; - @Override + @Override public String getInstallPath() { - return installPath; - } + return installPath; + } - @Override + @Override public long getTemplateSize() { - return templateSize; - } + return templateSize; + } - public long getPoolId() { - return poolId; - } + public long getPoolId() { + return poolId; + } - public void setpoolId(long poolId) { - this.poolId = poolId; - } + public void setpoolId(long poolId) { + this.poolId = poolId; + } - @Override + @Override public long getTemplateId() { - return templateId; - } + return templateId; + } - @Override + @Override public void setTemplateId(long templateId) { - this.templateId = templateId; - } + this.templateId = templateId; + } - @Override + @Override public int getDownloadPercent() { - return downloadPercent; - } + return downloadPercent; + } - @Override + @Override public void setDownloadPercent(int downloadPercent) { - this.downloadPercent = downloadPercent; - } + this.downloadPercent = downloadPercent; + } - @Override + @Override public void setDownloadState(Status downloadState) { - this.downloadState = downloadState; - } + this.downloadState = downloadState; + } - @Override + @Override public long getId() { - return id; - } + return id; + } - @Override + @Override public Date getCreated() { - return created; - } + return created; + } - @Override + @Override public Date getLastUpdated() { - return lastUpdated; - } + return lastUpdated; + } - @Override + @Override public void setLastUpdated(Date date) { - lastUpdated = date; - } + lastUpdated = date; + } - @Override + @Override public void setInstallPath(String installPath) { - this.installPath = installPath; - } + this.installPath = installPath; + } - @Override + @Override public Status getDownloadState() { - return downloadState; - } + return downloadState; + } - public VMTemplateStoragePoolVO(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 VMTemplateStoragePoolVO(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 VMTemplateStoragePoolVO(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; - } + public VMTemplateStoragePoolVO(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 VMTemplateStoragePoolVO() { + protected VMTemplateStoragePoolVO() { - } + } - @Override + @Override public void setLocalDownloadPath(String localPath) { - this.localDownloadPath = localPath; - } + this.localDownloadPath = localPath; + } - @Override + @Override public String getLocalDownloadPath() { - return localDownloadPath; - } + return localDownloadPath; + } - @Override + @Override public void setErrorString(String errorString) { - this.errorString = errorString; - } + this.errorString = errorString; + } - @Override + @Override public String getErrorString() { - return errorString; - } + return errorString; + } - @Override + @Override public void setJobId(String jobId) { - this.jobId = jobId; - } + this.jobId = jobId; + } - @Override + @Override public String getJobId() { - return jobId; - } + return jobId; + } - public void setTemplateSize(long templateSize) { - this.templateSize = templateSize; - } + public void setTemplateSize(long templateSize) { + this.templateSize = templateSize; + } - public boolean getMarkedForGC() { - return markedForGC; - } + public boolean getMarkedForGC() { + return markedForGC; + } - public void setMarkedForGC(boolean markedForGC) { - this.markedForGC = markedForGC; - } + public void setMarkedForGC(boolean markedForGC) { + this.markedForGC = markedForGC; + } - @Override - public boolean equals(Object obj) { - if (obj instanceof VMTemplateStoragePoolVO) { - VMTemplateStoragePoolVO other = (VMTemplateStoragePoolVO)obj; - return (this.templateId==other.getTemplateId() && this.poolId==other.getPoolId()); - } - return false; - } + @Override + public boolean equals(Object obj) { + if (obj instanceof VMTemplateStoragePoolVO) { + VMTemplateStoragePoolVO other = (VMTemplateStoragePoolVO) 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 int hashCode() { + Long tid = new Long(templateId); + Long hid = new Long(poolId); + return tid.hashCode() + hid.hashCode(); + } - @Override + @Override public String toString() { - return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId").append("-").append(installPath).append("]").toString(); - } + return new StringBuilder("TmplPool[").append(id).append("-").append(templateId).append("-").append("poolId") + .append("-").append(installPath).append("]").toString(); + } @Override public State getState() { @@ -286,5 +297,4 @@ public class VMTemplateStoragePoolVO implements VMTemplateStorageResourceAssoc, return this.state; } - } diff --git a/engine/schema/src/com/cloud/storage/VMTemplateSwiftVO.java b/engine/schema/src/com/cloud/storage/VMTemplateSwiftVO.java index 6c7a73d3c05..de55fb6622f 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateSwiftVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateSwiftVO.java @@ -101,7 +101,8 @@ public class VMTemplateSwiftVO implements InternalIdentity { @Override public String toString() { - return new StringBuilder("TmplSwift[").append(id).append("-").append(templateId).append("-").append(swiftId).append("]").toString(); + return new StringBuilder("TmplSwift[").append(id).append("-").append(templateId).append("-").append(swiftId) + .append("]").toString(); } } diff --git a/engine/schema/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java index e64c83a8b5b..00c394fa1fa 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java @@ -41,92 +41,93 @@ import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateObject; @Entity -@Table(name="vm_template") +@Table(name = "vm_template") public class VMTemplateVO implements VirtualMachineTemplate, StateObject { @Id - @TableGenerator(name="vm_template_sq", table="sequence", pkColumnName="name", valueColumnName="value", pkColumnValue="vm_template_seq", allocationSize=1) - @Column(name="id", nullable = false) + @TableGenerator(name = "vm_template_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", + pkColumnValue = "vm_template_seq", allocationSize = 1) + @Column(name = "id", nullable = false) private long id; - @Column(name="format") + @Column(name = "format") private Storage.ImageFormat format; - @Column(name="unique_name") + @Column(name = "unique_name") private String uniqueName; - @Column(name="name") + @Column(name = "name") private String name = null; - @Column(name="public") + @Column(name = "public") private boolean publicTemplate = true; - @Column(name="featured") + @Column(name = "featured") private boolean featured; - @Column(name="type") + @Column(name = "type") private Storage.TemplateType templateType; - @Column(name="url") + @Column(name = "url") private String url = null; - @Column(name="hvm") + @Column(name = "hvm") private boolean requiresHvm; - @Column(name="bits") + @Column(name = "bits") private int bits; - @Temporal(value=TemporalType.TIMESTAMP) - @Column(name=GenericDao.CREATED_COLUMN) + @Temporal(value = TemporalType.TIMESTAMP) + @Column(name = GenericDao.CREATED_COLUMN) private Date created = null; - @Column(name=GenericDao.REMOVED) + @Column(name = GenericDao.REMOVED) @Temporal(TemporalType.TIMESTAMP) private Date removed; - @Column(name="account_id") + @Column(name = "account_id") private long accountId; - @Column(name="checksum") + @Column(name = "checksum") private String checksum; - @Column(name="display_text", length=4096) + @Column(name = "display_text", length = 4096) private String displayText; - @Column(name="enable_password") + @Column(name = "enable_password") private boolean enablePassword; - @Column(name="guest_os_id") + @Column(name = "guest_os_id") private long guestOSId; - @Column(name="bootable") + @Column(name = "bootable") private boolean bootable = true; - @Column(name="prepopulate") + @Column(name = "prepopulate") private boolean prepopulate = false; - @Column(name="cross_zones") + @Column(name = "cross_zones") private boolean crossZones = false; - @Column(name="hypervisor_type") - @Enumerated(value=EnumType.STRING) + @Column(name = "hypervisor_type") + @Enumerated(value = EnumType.STRING) private HypervisorType hypervisorType; - @Column(name="extractable") + @Column(name = "extractable") private boolean extractable = true; - @Column(name="source_template_id") + @Column(name = "source_template_id") private Long sourceTemplateId; - @Column(name="template_tag") + @Column(name = "template_tag") private String templateTag; - @Column(name="uuid") + @Column(name = "uuid") private String uuid; - @Column(name="sort_key") + @Column(name = "sort_key") private int sortKey; - @Column(name="enable_sshkey") + @Column(name = "enable_sshkey") private boolean enableSshKey; @Column(name = "size") @@ -135,7 +136,7 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject { List listByDomainId(long domainId); + List findPrivateDiskOffering(); - List findPublicDiskOfferings(); + + List findPublicDiskOfferings(); + DiskOfferingVO findByUniqueName(String uniqueName); + DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering); - + } diff --git a/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java index 1f68c5082ff..0c77a8a8600 100644 --- a/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/DiskOfferingDaoImpl.java @@ -22,7 +22,6 @@ import java.util.List; import javax.ejb.Local; import javax.persistence.EntityExistsException; -import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.storage.DiskOfferingVO; @@ -35,10 +34,8 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Op; @Component -@Local(value={DiskOfferingDao.class}) +@Local(value = { DiskOfferingDao.class }) public class DiskOfferingDaoImpl extends GenericDaoBase implements DiskOfferingDao { - private static final Logger s_logger = Logger.getLogger(DiskOfferingDaoImpl.class); - private final SearchBuilder DomainIdSearch; private final SearchBuilder PrivateDiskOfferingSearch; private final SearchBuilder PublicDiskOfferingSearch; @@ -46,25 +43,27 @@ public class DiskOfferingDaoImpl extends GenericDaoBase im private final Attribute _typeAttr; protected DiskOfferingDaoImpl() { - DomainIdSearch = createSearchBuilder(); + DomainIdSearch = createSearchBuilder(); DomainIdSearch.and("domainId", DomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ); DomainIdSearch.and("removed", DomainIdSearch.entity().getRemoved(), SearchCriteria.Op.NULL); DomainIdSearch.done(); - - PrivateDiskOfferingSearch = createSearchBuilder(); - PrivateDiskOfferingSearch.and("diskSize", PrivateDiskOfferingSearch.entity().getDiskSize(), SearchCriteria.Op.EQ); + + PrivateDiskOfferingSearch = createSearchBuilder(); + PrivateDiskOfferingSearch.and("diskSize", PrivateDiskOfferingSearch.entity().getDiskSize(), + SearchCriteria.Op.EQ); PrivateDiskOfferingSearch.done(); - + PublicDiskOfferingSearch = createSearchBuilder(); - PublicDiskOfferingSearch.and("domainId", PublicDiskOfferingSearch.entity().getDomainId(), SearchCriteria.Op.NULL); + PublicDiskOfferingSearch.and("domainId", PublicDiskOfferingSearch.entity().getDomainId(), + SearchCriteria.Op.NULL); PublicDiskOfferingSearch.and("system", PublicDiskOfferingSearch.entity().getSystemUse(), SearchCriteria.Op.EQ); PublicDiskOfferingSearch.and("removed", PublicDiskOfferingSearch.entity().getRemoved(), SearchCriteria.Op.NULL); PublicDiskOfferingSearch.done(); - + UniqueNameSearch = createSearchBuilder(); UniqueNameSearch.and("name", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ); UniqueNameSearch.done(); - + _typeAttr = _allAttributes.get("type"); } @@ -72,29 +71,31 @@ public class DiskOfferingDaoImpl extends GenericDaoBase im public List listByDomainId(long domainId) { SearchCriteria sc = DomainIdSearch.create(); sc.setParameters("domainId", domainId); - // FIXME: this should not be exact match, but instead should find all available disk offerings from parent domains + // FIXME: this should not be exact match, but instead should find all + // available disk offerings from parent domains return listBy(sc); } - + @Override public List findPrivateDiskOffering() { SearchCriteria sc = PrivateDiskOfferingSearch.create(); sc.setParameters("diskSize", 0); return listBy(sc); } - + @Override - public List searchIncludingRemoved(SearchCriteria sc, final Filter filter, final Boolean lock, final boolean cache) { + public List searchIncludingRemoved(SearchCriteria sc, final Filter filter, + final Boolean lock, final boolean cache) { sc.addAnd(_typeAttr, Op.EQ, Type.Disk); return super.searchIncludingRemoved(sc, filter, lock, cache); } - + @Override public List customSearchIncludingRemoved(SearchCriteria sc, final Filter filter) { sc.addAnd(_typeAttr, Op.EQ, Type.Disk); return super.customSearchIncludingRemoved(sc, filter); } - + @Override protected List executeList(final String sql, final Object... params) { StringBuilder builder = new StringBuilder(sql); @@ -104,17 +105,17 @@ public class DiskOfferingDaoImpl extends GenericDaoBase im } else { builder.insert(index + 6, "type=? "); } - + return super.executeList(sql, Type.Disk, params); } - + @Override - public List findPublicDiskOfferings(){ - SearchCriteria sc = PublicDiskOfferingSearch.create(); - sc.setParameters("system", false); - return listBy(sc); + public List findPublicDiskOfferings() { + SearchCriteria sc = PublicDiskOfferingSearch.create(); + sc.setParameters("system", false); + return listBy(sc); } - + @Override public DiskOfferingVO findByUniqueName(String uniqueName) { SearchCriteria sc = UniqueNameSearch.create(); @@ -123,10 +124,10 @@ public class DiskOfferingDaoImpl extends GenericDaoBase im if (vos.size() == 0) { return null; } - + return vos.get(0); } - + @Override public DiskOfferingVO persistDeafultDiskOffering(DiskOfferingVO offering) { assert offering.getUniqueName() != null : "unique name shouldn't be null for the disk offering"; @@ -141,7 +142,7 @@ public class DiskOfferingDaoImpl extends GenericDaoBase im return findByUniqueName(offering.getUniqueName()); } } - + @Override public boolean remove(Long id) { DiskOfferingVO diskOffering = createForUpdate(); diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDao.java b/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDao.java index 0f7ea327f15..61fec36d526 100644 --- a/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDao.java +++ b/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDao.java @@ -20,5 +20,5 @@ import com.cloud.storage.GuestOSCategoryVO; import com.cloud.utils.db.GenericDao; public interface GuestOSCategoryDao extends GenericDao { - + } diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java index d017b996d5d..0637ecbf4ff 100644 --- a/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/GuestOSCategoryDaoImpl.java @@ -24,11 +24,11 @@ import com.cloud.storage.GuestOSCategoryVO; import com.cloud.utils.db.GenericDaoBase; @Component -@Local (value={GuestOSCategoryDao.class}) +@Local(value = { GuestOSCategoryDao.class }) public class GuestOSCategoryDaoImpl extends GenericDaoBase implements GuestOSCategoryDao { - - protected GuestOSCategoryDaoImpl() { - } - + protected GuestOSCategoryDaoImpl() { + + } + } diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSDao.java b/engine/schema/src/com/cloud/storage/dao/GuestOSDao.java index 19e423bfefd..a9d0cdb8279 100755 --- a/engine/schema/src/com/cloud/storage/dao/GuestOSDao.java +++ b/engine/schema/src/com/cloud/storage/dao/GuestOSDao.java @@ -22,5 +22,5 @@ import com.cloud.utils.db.GenericDao; public interface GuestOSDao extends GenericDao { GuestOSVO listByDisplayName(String displayName); - + } diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/GuestOSDaoImpl.java index c39fae8ea8d..618578524c6 100755 --- a/engine/schema/src/com/cloud/storage/dao/GuestOSDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/GuestOSDaoImpl.java @@ -16,32 +16,28 @@ // under the License. package com.cloud.storage.dao; -import java.util.List; - import javax.ejb.Local; import org.springframework.stereotype.Component; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -@Local (value={GuestOSDao.class}) +@Local(value = { GuestOSDao.class }) public class GuestOSDaoImpl extends GenericDaoBase implements GuestOSDao { - - + protected final SearchBuilder Search; - - protected GuestOSDaoImpl() { + + protected GuestOSDaoImpl() { Search = createSearchBuilder(); Search.and("display_name", Search.entity().getDisplayName(), SearchCriteria.Op.EQ); Search.done(); - } - - @Override + } + + @Override public GuestOSVO listByDisplayName(String displayName) { SearchCriteria sc = Search.create(); sc.setParameters("display_name", displayName); diff --git a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDao.java b/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDao.java index 0ad60b50ee8..146e180fd07 100644 --- a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDao.java +++ b/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDao.java @@ -18,42 +18,54 @@ package com.cloud.storage.dao; import java.util.List; - import com.cloud.storage.LaunchPermissionVO; import com.cloud.storage.VMTemplateVO; import com.cloud.utils.db.GenericDao; public interface LaunchPermissionDao extends GenericDao { /** - * remove the ability to launch vms from the given template for the given account names which are valid in the given domain - * @param templateId id of the template to modify launch permissions - * @param accountIds list of account ids + * remove the ability to launch vms from the given template for the given + * account names which are valid in the given domain + * + * @param templateId + * id of the template to modify launch permissions + * @param accountIds + * list of account ids */ void removePermissions(long templateId, List accountIds); /** * remove all launch permissions associated with a template + * * @param templateId */ void removeAllPermissions(long templateId); /** * Find a launch permission by templateId, accountName, and domainId - * @param templateId the id of the template to search for - * @param accountId the id of the account for which permission is being searched + * + * @param templateId + * the id of the template to search for + * @param accountId + * the id of the account for which permission is being searched * @return launch permission if found, null otherwise */ LaunchPermissionVO findByTemplateAndAccount(long templateId, long accountId); /** * List all launch permissions for the given template - * @param templateId id of the template for which launch permissions will be queried + * + * @param templateId + * id of the template for which launch permissions will be + * queried * @return list of launch permissions */ List findByTemplate(long templateId); /** - * List all templates for which permission to launch instances has been granted to the given account + * List all templates for which permission to launch instances has been + * granted to the given account + * * @param accountId * @return */ diff --git a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java index 286b1d9ce3f..3e32f1a9529 100644 --- a/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/LaunchPermissionDaoImpl.java @@ -39,26 +39,27 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @Component -@Local(value={LaunchPermissionDao.class}) +@Local(value = { LaunchPermissionDao.class }) public class LaunchPermissionDaoImpl extends GenericDaoBase implements LaunchPermissionDao { private static final Logger s_logger = Logger.getLogger(LaunchPermissionDaoImpl.class); - private static final String REMOVE_LAUNCH_PERMISSION = "DELETE FROM `cloud`.`launch_permission`" + - " WHERE template_id = ? AND account_id = ?"; + private static final String REMOVE_LAUNCH_PERMISSION = "DELETE FROM `cloud`.`launch_permission`" + + " WHERE template_id = ? AND account_id = ?"; - private static final String LIST_PERMITTED_TEMPLATES = "SELECT t.id, t.unique_name, t.name, t.public, t.format, t.type, t.hvm, t.bits, t.url, t.created, t.account_id, t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.featured" + - " FROM `cloud`.`vm_template` t INNER JOIN (SELECT lp.template_id as lptid" + - " FROM `cloud`.`launch_permission` lp" + - " WHERE lp.account_id = ?) joinlp" + - " WHERE t.id = joinlp.lptid" + - " ORDER BY t.created DESC"; + private static final String LIST_PERMITTED_TEMPLATES = "SELECT t.id, t.unique_name, t.name, t.public, t.format, t.type, t.hvm, t.bits, t.url, t.created, t.account_id, t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.featured" + + " FROM `cloud`.`vm_template` t INNER JOIN (SELECT lp.template_id as lptid" + + " FROM `cloud`.`launch_permission` lp" + + " WHERE lp.account_id = ?) joinlp" + + " WHERE t.id = joinlp.lptid" + " ORDER BY t.created DESC"; private final SearchBuilder TemplateAndAccountSearch; private final SearchBuilder TemplateIdSearch; protected LaunchPermissionDaoImpl() { TemplateAndAccountSearch = createSearchBuilder(); - TemplateAndAccountSearch.and("templateId", TemplateAndAccountSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateAndAccountSearch.and("accountId", TemplateAndAccountSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + TemplateAndAccountSearch.and("templateId", TemplateAndAccountSearch.entity().getTemplateId(), + SearchCriteria.Op.EQ); + TemplateAndAccountSearch.and("accountId", TemplateAndAccountSearch.entity().getAccountId(), + SearchCriteria.Op.EQ); TemplateAndAccountSearch.done(); TemplateIdSearch = createSearchBuilder(); @@ -138,9 +139,13 @@ public class LaunchPermissionDaoImpl extends GenericDaoBase implements S3Dao { } - // NOTE: Excluded listAll / shuffle operation implemented in SwiftDaoImpl ... + // NOTE: Excluded listAll / shuffle operation implemented in + // SwiftDaoImpl ... return null; diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java index 46f2fa9396b..a58902121cc 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java @@ -27,24 +27,40 @@ import com.cloud.utils.fsm.StateDao; import java.util.List; public interface SnapshotDao extends GenericDao, StateDao { - List listByVolumeId(long volumeId); - List listByVolumeId(Filter filter, long volumeId); - SnapshotVO findNextSnapshot(long parentSnapId); - long getLastSnapshot(long volumeId, DataStoreRole role); + List listByVolumeId(long volumeId); + + List listByVolumeId(Filter filter, long volumeId); + + SnapshotVO findNextSnapshot(long parentSnapId); + + long getLastSnapshot(long volumeId, DataStoreRole role); + List listByVolumeIdType(long volumeId, Type type); + List listByVolumeIdIncludingRemoved(long volumeId); + List listByBackupUuid(long volumeId, String backupUuid); + long updateSnapshotVersion(long volumeId, String from, String to); + List listByVolumeIdVersion(long volumeId, String version); + Long getSecHostId(long volumeId); + long updateSnapshotSecHost(long dcId, long secHostId); + public Long countSnapshotsForAccount(long accountId); + List listByInstanceId(long instanceId, Snapshot.State... status); + List listByStatus(long volumeId, Snapshot.State... status); + List listAllByStatus(Snapshot.State... status); + /** - * Gets the Total Secondary Storage space (in bytes) used by snapshots allocated for an account - * + * Gets the Total Secondary Storage space (in bytes) used by snapshots + * allocated for an account + * * @param account * @return total Secondary Storage space allocated */ diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java index a3493890a59..f5319ea120a 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -52,10 +52,10 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDao; @Component -@Local (value={SnapshotDao.class}) +@Local(value = { SnapshotDao.class }) public class SnapshotDaoImpl extends GenericDaoBase implements SnapshotDao { public static final Logger s_logger = Logger.getLogger(SnapshotDaoImpl.class.getName()); - //TODO: we should remove these direct sqls + // TODO: we should remove these direct sqls private static final String GET_LAST_SNAPSHOT = "SELECT snapshots.id FROM snapshot_store_ref, snapshots where snapshots.id = snapshot_store_ref.snapshot_id AND snapshosts.volume_id = ? AND snapshot_store_ref.role = ? ORDER BY created DESC"; private static final String UPDATE_SNAPSHOT_VERSION = "UPDATE snapshots SET version = ? WHERE volume_id = ? AND version = ?"; private static final String GET_SECHOST_ID = "SELECT store_id FROM snapshots, snapshot_store_ref where snapshots.id = snapshot_store_ref.snapshot_id AND volume_id = ? AND backup_snap_id IS NOT NULL AND sechost_id IS NOT NULL LIMIT 1"; @@ -71,9 +71,12 @@ public class SnapshotDaoImpl extends GenericDaoBase implements private SearchBuilder StatusSearch; private GenericSearchBuilder CountSnapshotsByAccount; private GenericSearchBuilder secondaryStorageSearch; - @Inject ResourceTagDao _tagsDao; - @Inject protected VMInstanceDao _instanceDao; - @Inject protected VolumeDao _volumeDao; + @Inject + ResourceTagDao _tagsDao; + @Inject + protected VMInstanceDao _instanceDao; + @Inject + protected VolumeDao _volumeDao; @Override public SnapshotVO findNextSnapshot(long snapshotId) { @@ -83,20 +86,19 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } @Override - public List listByBackupUuid(long volumeId, String backupUuid) { + public List listByBackupUuid(long volumeId, String backupUuid) { SearchCriteria sc = backupUuidSearch.create(); sc.setParameters("backupUuid", backupUuid); return listBy(sc, null); } @Override - public List listByVolumeIdType(long volumeId, Type type ) { + public List listByVolumeIdType(long volumeId, Type type) { return listByVolumeIdType(null, volumeId, type); } - @Override - public List listByVolumeIdVersion(long volumeId, String version ) { + public List listByVolumeIdVersion(long volumeId, String version) { return listByVolumeIdVersion(null, volumeId, version); } @@ -106,27 +108,27 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } @Override - public List listByVolumeId(Filter filter, long volumeId ) { + public List listByVolumeId(Filter filter, long volumeId) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); return listBy(sc, filter); } - @Override + @Override public List listByVolumeIdIncludingRemoved(long volumeId) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); return listIncludingRemovedBy(sc, null); } - public List listByVolumeIdType(Filter filter, long volumeId, Type type ) { + public List listByVolumeIdType(Filter filter, long volumeId, Type type) { SearchCriteria sc = VolumeIdTypeSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("type", type.ordinal()); return listBy(sc, filter); } - public List listByVolumeIdVersion(Filter filter, long volumeId, String version ) { + public List listByVolumeIdVersion(Filter filter, long volumeId, String version) { SearchCriteria sc = VolumeIdVersionSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("version", version); @@ -151,15 +153,17 @@ public class SnapshotDaoImpl extends GenericDaoBase implements VolumeIdVersionSearch.and("volumeId", VolumeIdVersionSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdVersionSearch.and("version", VolumeIdVersionSearch.entity().getVersion(), SearchCriteria.Op.EQ); VolumeIdVersionSearch.done(); -/* - ParentIdSearch = createSearchBuilder(); - ParentIdSearch.and("prevSnapshotId", ParentIdSearch.entity().getPrevSnapshotId(), SearchCriteria.Op.EQ); - ParentIdSearch.done(); - - backupUuidSearch = createSearchBuilder(); - backupUuidSearch.and("backupUuid", backupUuidSearch.entity().getBackupSnapshotId(), SearchCriteria.Op.EQ); - backupUuidSearch.done(); -*/ + /* + * ParentIdSearch = createSearchBuilder(); + * ParentIdSearch.and("prevSnapshotId", + * ParentIdSearch.entity().getPrevSnapshotId(), SearchCriteria.Op.EQ); + * ParentIdSearch.done(); + * + * backupUuidSearch = createSearchBuilder(); + * backupUuidSearch.and("backupUuid", + * backupUuidSearch.entity().getBackupSnapshotId(), + * SearchCriteria.Op.EQ); backupUuidSearch.done(); + */ AccountIdSearch = createSearchBuilder(); AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.done(); @@ -183,9 +187,11 @@ public class SnapshotDaoImpl extends GenericDaoBase implements SearchBuilder volumeSearch = _volumeDao.createSearchBuilder(); volumeSearch.and("state", volumeSearch.entity().getState(), SearchCriteria.Op.EQ); - volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity().getInstanceId(), JoinType.INNER); + volumeSearch.join("instanceVolumes", instanceSearch, instanceSearch.entity().getId(), volumeSearch.entity() + .getInstanceId(), JoinType.INNER); - InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch.entity().getVolumeId(), JoinType.INNER); + InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch + .entity().getVolumeId(), JoinType.INNER); InstanceIdSearch.done(); secondaryStorageSearch = createSearchBuilder(SumCount.class); @@ -212,6 +218,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements } return null; } + @Override public long getLastSnapshot(long volumeId, DataStoreRole role) { Transaction txn = Transaction.currentTxn(); @@ -268,30 +275,30 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public Long countSnapshotsForAccount(long accountId) { - SearchCriteria sc = CountSnapshotsByAccount.create(); + SearchCriteria sc = CountSnapshotsByAccount.create(); sc.setParameters("account", accountId); return customSearch(sc, null).get(0); } @Override - public List listByInstanceId(long instanceId, Snapshot.State... status) { - SearchCriteria sc = this.InstanceIdSearch.create(); + public List listByInstanceId(long instanceId, Snapshot.State... status) { + SearchCriteria sc = this.InstanceIdSearch.create(); - if (status != null && status.length != 0) { - sc.setParameters("status", (Object[])status); - } + if (status != null && status.length != 0) { + sc.setParameters("status", (Object[]) status); + } - sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready); - sc.setJoinParameters("instanceVolumes", "instanceId", instanceId); + sc.setJoinParameters("instanceSnapshots", "state", Volume.State.Ready); + sc.setJoinParameters("instanceVolumes", "instanceId", instanceId); return listBy(sc, null); } @Override public List listByStatus(long volumeId, Snapshot.State... status) { - SearchCriteria sc = this.StatusSearch.create(); - sc.setParameters("volumeId", volumeId); - sc.setParameters("status", (Object[])status); - return listBy(sc, null); + SearchCriteria sc = this.StatusSearch.create(); + sc.setParameters("volumeId", volumeId); + sc.setParameters("status", (Object[]) status); + return listBy(sc, null); } @Override @@ -311,7 +318,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements @Override public List listAllByStatus(Snapshot.State... status) { SearchCriteria sc = this.StatusSearch.create(); - sc.setParameters("status", (Object[])status); + sc.setParameters("status", (Object[]) status); return listBy(sc, null); } @@ -319,7 +326,7 @@ public class SnapshotDaoImpl extends GenericDaoBase implements public boolean updateState(State currentState, Event event, State nextState, SnapshotVO snapshot, Object data) { Transaction txn = Transaction.currentTxn(); txn.start(); - SnapshotVO snapshotVO = (SnapshotVO)snapshot; + SnapshotVO snapshotVO = (SnapshotVO) snapshot; snapshotVO.setState(nextState); super.update(snapshotVO.getId(), snapshotVO); txn.commit(); diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java index 467d491d779..f65b5839f75 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDao.java @@ -28,11 +28,17 @@ import com.cloud.utils.db.GenericDao; * Data Access Object for snapshot_policy table */ public interface SnapshotPolicyDao extends GenericDao { - List listByVolumeId(long volumeId); - List listByVolumeId(long volumeId, Filter filter); + List listByVolumeId(long volumeId); + + List listByVolumeId(long volumeId, Filter filter); + Pair, Integer> listAndCountByVolumeId(long volumeId); + Pair, Integer> listAndCountByVolumeId(long volumeId, Filter filter); - SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType); + + SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType); + List listActivePolicies(); + SnapshotPolicyVO findOneByVolume(long volumeId); } diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java index 3f894a22640..662ad4354a4 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotPolicyDaoImpl.java @@ -16,7 +16,6 @@ // under the License. package com.cloud.storage.dao; - import java.util.List; import javax.ejb.Local; @@ -32,33 +31,33 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -@Local (value={SnapshotPolicyDao.class}) +@Local(value = { SnapshotPolicyDao.class }) public class SnapshotPolicyDaoImpl extends GenericDaoBase implements SnapshotPolicyDao { - private final SearchBuilder VolumeIdSearch; - private final SearchBuilder VolumeIdIntervalSearch; - private final SearchBuilder ActivePolicySearch; - - @Override - public SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType) { - SearchCriteria sc = VolumeIdIntervalSearch.create(); + private final SearchBuilder VolumeIdSearch; + private final SearchBuilder VolumeIdIntervalSearch; + private final SearchBuilder ActivePolicySearch; + + @Override + public SnapshotPolicyVO findOneByVolumeInterval(long volumeId, IntervalType intvType) { + SearchCriteria sc = VolumeIdIntervalSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("interval", intvType.ordinal()); - return findOneBy(sc); - } - - @Override + return findOneBy(sc); + } + + @Override public SnapshotPolicyVO findOneByVolume(long volumeId) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); sc.setParameters("active", true); return findOneBy(sc); } - - @Override - public List listByVolumeId(long volumeId) { - return listByVolumeId(volumeId, null); - } - + + @Override + public List listByVolumeId(long volumeId) { + return listByVolumeId(volumeId, null); + } + @Override public List listByVolumeId(long volumeId, Filter filter) { SearchCriteria sc = VolumeIdSearch.create(); @@ -66,7 +65,7 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase, Integer> listAndCountByVolumeId(long volumeId) { return listAndCountByVolumeId(volumeId, null); @@ -85,12 +84,12 @@ public class SnapshotPolicyDaoImpl extends GenericDaoBase sc = ActivePolicySearch.create(); sc.setParameters("active", true); return listIncludingRemovedBy(sc); - } + } } \ No newline at end of file diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDao.java index 0419e2836a0..7ca0a3915f5 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDao.java @@ -16,10 +16,9 @@ // under the License. package com.cloud.storage.dao; - import java.util.Date; import java.util.List; -import com.cloud.storage.SnapshotPolicyVO; + import com.cloud.storage.SnapshotScheduleVO; import com.cloud.utils.db.GenericDao; @@ -28,7 +27,7 @@ import com.cloud.utils.db.GenericDao; */ public interface SnapshotScheduleDao extends GenericDao { - List getCoincidingSnapshotSchedules(long volumeId, Date date); + List getCoincidingSnapshotSchedules(long volumeId, Date date); List getSchedulesToExecute(Date currentTimestamp); diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java index c01644e0918..72d47fa4dcc 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotScheduleDaoImpl.java @@ -30,60 +30,63 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -@Local (value={SnapshotScheduleDao.class}) +@Local(value = { SnapshotScheduleDao.class }) public class SnapshotScheduleDaoImpl extends GenericDaoBase implements SnapshotScheduleDao { - protected final SearchBuilder executableSchedulesSearch; - protected final SearchBuilder coincidingSchedulesSearch; + protected final SearchBuilder executableSchedulesSearch; + protected final SearchBuilder coincidingSchedulesSearch; private final SearchBuilder VolumeIdSearch; private final SearchBuilder VolumeIdPolicyIdSearch; - - - protected SnapshotScheduleDaoImpl() { - - executableSchedulesSearch = createSearchBuilder(); - executableSchedulesSearch.and("scheduledTimestamp", executableSchedulesSearch.entity().getScheduledTimestamp(), SearchCriteria.Op.LT); - executableSchedulesSearch.and("asyncJobId", executableSchedulesSearch.entity().getAsyncJobId(), SearchCriteria.Op.NULL); + + protected SnapshotScheduleDaoImpl() { + + executableSchedulesSearch = createSearchBuilder(); + executableSchedulesSearch.and("scheduledTimestamp", executableSchedulesSearch.entity().getScheduledTimestamp(), + SearchCriteria.Op.LT); + executableSchedulesSearch.and("asyncJobId", executableSchedulesSearch.entity().getAsyncJobId(), + SearchCriteria.Op.NULL); executableSchedulesSearch.done(); - + coincidingSchedulesSearch = createSearchBuilder(); - coincidingSchedulesSearch.and("volumeId", coincidingSchedulesSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); - coincidingSchedulesSearch.and("scheduledTimestamp", coincidingSchedulesSearch.entity().getScheduledTimestamp(), SearchCriteria.Op.LT); - coincidingSchedulesSearch.and("asyncJobId", coincidingSchedulesSearch.entity().getAsyncJobId(), SearchCriteria.Op.NULL); + coincidingSchedulesSearch.and("volumeId", coincidingSchedulesSearch.entity().getVolumeId(), + SearchCriteria.Op.EQ); + coincidingSchedulesSearch.and("scheduledTimestamp", coincidingSchedulesSearch.entity().getScheduledTimestamp(), + SearchCriteria.Op.LT); + coincidingSchedulesSearch.and("asyncJobId", coincidingSchedulesSearch.entity().getAsyncJobId(), + SearchCriteria.Op.NULL); coincidingSchedulesSearch.done(); - + VolumeIdSearch = createSearchBuilder(); VolumeIdSearch.and("volumeId", VolumeIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdSearch.done(); - + VolumeIdPolicyIdSearch = createSearchBuilder(); VolumeIdPolicyIdSearch.and("volumeId", VolumeIdPolicyIdSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); VolumeIdPolicyIdSearch.and("policyId", VolumeIdPolicyIdSearch.entity().getPolicyId(), SearchCriteria.Op.EQ); VolumeIdPolicyIdSearch.done(); - - } - - /** - * {@inheritDoc} - */ - @Override - public List getCoincidingSnapshotSchedules(long volumeId, Date date) { - SearchCriteria sc = coincidingSchedulesSearch.create(); - sc.setParameters("volumeId", volumeId); - sc.setParameters("scheduledTimestamp", date); - // Don't return manual snapshots. They will be executed through another code path. + + } + + /** + * {@inheritDoc} + */ + @Override + public List getCoincidingSnapshotSchedules(long volumeId, Date date) { + SearchCriteria sc = coincidingSchedulesSearch.create(); + sc.setParameters("volumeId", volumeId); + sc.setParameters("scheduledTimestamp", date); + // Don't return manual snapshots. They will be executed through another + // code path. sc.addAnd("policyId", SearchCriteria.Op.NEQ, 1L); return listBy(sc); - } + } - @Override public SnapshotScheduleVO findOneByVolume(long volumeId) { SearchCriteria sc = VolumeIdSearch.create(); sc.setParameters("volumeId", volumeId); return findOneBy(sc); } - - + @Override public SnapshotScheduleVO findOneByVolumePolicy(long volumeId, long policyId) { SearchCriteria sc = VolumeIdPolicyIdSearch.create(); @@ -91,8 +94,9 @@ public class SnapshotScheduleDaoImpl extends GenericDaoBase getSchedulesToExecute(Date currentTimestamp) { @@ -100,9 +104,9 @@ public class SnapshotScheduleDaoImpl extends GenericDaoBase snapshotSchedules = listBy(sc); - // This will return only one schedule because of a DB uniqueness constraint. + // This will return only one schedule because of a DB uniqueness + // constraint. assert (snapshotSchedules.size() <= 1); if (snapshotSchedules.isEmpty()) { return null; - } - else { + } else { return snapshotSchedules.get(0); } } - + } \ No newline at end of file diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java index 38b525330f2..8952e6cb154 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolDetailsDaoImpl.java @@ -32,11 +32,12 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @Component -@Local(value=StoragePoolDetailsDao.class) -public class StoragePoolDetailsDaoImpl extends GenericDaoBase implements StoragePoolDetailsDao { - +@Local(value = StoragePoolDetailsDao.class) +public class StoragePoolDetailsDaoImpl extends GenericDaoBase implements + StoragePoolDetailsDao { + protected final SearchBuilder PoolSearch; - + protected StoragePoolDetailsDaoImpl() { super(); PoolSearch = createSearchBuilder(); @@ -44,13 +45,13 @@ public class StoragePoolDetailsDaoImpl extends GenericDaoBase details) { Transaction txn = Transaction.currentTxn(); SearchCriteria sc = PoolSearch.create(); sc.setParameters("pool", poolId); - + txn.start(); expunge(sc); for (Map.Entry entry : details.entrySet()) { @@ -59,19 +60,19 @@ public class StoragePoolDetailsDaoImpl extends GenericDaoBase getDetails(long poolId) { - SearchCriteria sc = PoolSearch.create(); - sc.setParameters("pool", poolId); - - List details = listBy(sc); - Map detailsMap = new HashMap(); - for (StoragePoolDetailVO detail : details) { - detailsMap.put(detail.getName(), detail.getValue()); - } - - return detailsMap; + SearchCriteria sc = PoolSearch.create(); + sc.setParameters("pool", poolId); + + List details = listBy(sc); + Map detailsMap = new HashMap(); + for (StoragePoolDetailVO detail : details) { + detailsMap.put(detail.getName(), detail.getValue()); + } + + return detailsMap; } @Override diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java index 4f509d14041..730216b82b0 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolHostDaoImpl.java @@ -46,13 +46,16 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase listByHostId(long hostId) { SearchCriteria sc = HostSearch.create(); @@ -113,7 +116,8 @@ public class StoragePoolHostDaoImpl extends GenericDaoBase void removePendingJobsOnMsRestart(long msId, long poolId); List searchForPoolIdsForPendingWorkJobs(long msId); - + } diff --git a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java index 360a814f59a..052bae4fc78 100644 --- a/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/StoragePoolWorkDaoImpl.java @@ -35,43 +35,53 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @Component -@Local(value={StoragePoolWorkDao.class}) @DB(txn=false) -public class StoragePoolWorkDaoImpl extends GenericDaoBase implements StoragePoolWorkDao { +@Local(value = { StoragePoolWorkDao.class }) +@DB(txn = false) +public class StoragePoolWorkDaoImpl extends GenericDaoBase implements StoragePoolWorkDao { protected final SearchBuilder PendingWorkForPrepareForMaintenanceSearch; protected final SearchBuilder PendingWorkForCancelMaintenanceSearch; protected final SearchBuilder PoolAndVmIdSearch; protected final SearchBuilder PendingJobsForDeadMs; - + private final String FindPoolIds = "SELECT distinct storage_pool_work.pool_id FROM storage_pool_work WHERE mgmt_server_id = ?"; - + protected StoragePoolWorkDaoImpl() { PendingWorkForPrepareForMaintenanceSearch = createSearchBuilder(); - PendingWorkForPrepareForMaintenanceSearch.and("poolId", PendingWorkForPrepareForMaintenanceSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - PendingWorkForPrepareForMaintenanceSearch.and("stoppedForMaintenance", PendingWorkForPrepareForMaintenanceSearch.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ); - PendingWorkForPrepareForMaintenanceSearch.and("startedAfterMaintenance", PendingWorkForPrepareForMaintenanceSearch.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ); + PendingWorkForPrepareForMaintenanceSearch.and("poolId", PendingWorkForPrepareForMaintenanceSearch.entity() + .getPoolId(), SearchCriteria.Op.EQ); + PendingWorkForPrepareForMaintenanceSearch.and("stoppedForMaintenance", + PendingWorkForPrepareForMaintenanceSearch.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ); + PendingWorkForPrepareForMaintenanceSearch.and("startedAfterMaintenance", + PendingWorkForPrepareForMaintenanceSearch.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ); PendingWorkForPrepareForMaintenanceSearch.done(); - + PendingWorkForCancelMaintenanceSearch = createSearchBuilder(); - PendingWorkForCancelMaintenanceSearch.and("poolId", PendingWorkForCancelMaintenanceSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - PendingWorkForCancelMaintenanceSearch.and("stoppedForMaintenance", PendingWorkForCancelMaintenanceSearch.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ); - PendingWorkForCancelMaintenanceSearch.and("startedAfterMaintenance", PendingWorkForCancelMaintenanceSearch.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ); + PendingWorkForCancelMaintenanceSearch.and("poolId", PendingWorkForCancelMaintenanceSearch.entity().getPoolId(), + SearchCriteria.Op.EQ); + PendingWorkForCancelMaintenanceSearch.and("stoppedForMaintenance", PendingWorkForCancelMaintenanceSearch + .entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ); + PendingWorkForCancelMaintenanceSearch.and("startedAfterMaintenance", PendingWorkForCancelMaintenanceSearch + .entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ); PendingWorkForCancelMaintenanceSearch.done(); PoolAndVmIdSearch = createSearchBuilder(); PoolAndVmIdSearch.and("poolId", PoolAndVmIdSearch.entity().getPoolId(), SearchCriteria.Op.EQ); PoolAndVmIdSearch.and("vmId", PoolAndVmIdSearch.entity().getVmId(), SearchCriteria.Op.EQ); PoolAndVmIdSearch.done(); - + PendingJobsForDeadMs = createSearchBuilder(); - PendingJobsForDeadMs.and("managementServerId", PendingJobsForDeadMs.entity().getManagementServerId(), SearchCriteria.Op.EQ); + PendingJobsForDeadMs.and("managementServerId", PendingJobsForDeadMs.entity().getManagementServerId(), + SearchCriteria.Op.EQ); PendingJobsForDeadMs.and("poolId", PendingJobsForDeadMs.entity().getPoolId(), SearchCriteria.Op.EQ); - PendingJobsForDeadMs.and("stoppedForMaintenance", PendingJobsForDeadMs.entity().isStoppedForMaintenance(), SearchCriteria.Op.EQ); - PendingJobsForDeadMs.and("startedAfterMaintenance", PendingJobsForDeadMs.entity().isStartedAfterMaintenance(), SearchCriteria.Op.EQ); + PendingJobsForDeadMs.and("stoppedForMaintenance", PendingJobsForDeadMs.entity().isStoppedForMaintenance(), + SearchCriteria.Op.EQ); + PendingJobsForDeadMs.and("startedAfterMaintenance", PendingJobsForDeadMs.entity().isStartedAfterMaintenance(), + SearchCriteria.Op.EQ); PendingJobsForDeadMs.done(); - + } - + @Override public List listPendingWorkForPrepareForMaintenanceByPoolId(long poolId) { SearchCriteria sc = PendingWorkForPrepareForMaintenanceSearch.create(); @@ -80,7 +90,7 @@ public class StoragePoolWorkDaoImpl extends GenericDaoBase listPendingWorkForCancelMaintenanceByPoolId(long poolId) { SearchCriteria sc = PendingWorkForCancelMaintenanceSearch.create(); @@ -89,7 +99,7 @@ public class StoragePoolWorkDaoImpl extends GenericDaoBase sc = PoolAndVmIdSearch.create(); @@ -97,22 +107,22 @@ public class StoragePoolWorkDaoImpl extends GenericDaoBase sc = PendingJobsForDeadMs.create(); sc.setParameters("managementServerId", msId); sc.setParameters("poolId", poolId); sc.setParameters("stoppedForMaintenance", true); - sc.setParameters("startedAfterMaintenance", false); + sc.setParameters("startedAfterMaintenance", false); remove(sc); } - + @Override @DB - public List searchForPoolIdsForPendingWorkJobs(long msId){ - + public List searchForPoolIdsForPendingWorkJobs(long msId) { + StringBuilder sql = new StringBuilder(FindPoolIds); Transaction txn = Transaction.currentTxn(); @@ -126,7 +136,7 @@ public class StoragePoolWorkDaoImpl extends GenericDaoBase implements SwiftDao { public static final Logger s_logger = Logger.getLogger(SwiftDaoImpl.class.getName()); diff --git a/engine/schema/src/com/cloud/storage/dao/UploadDao.java b/engine/schema/src/com/cloud/storage/dao/UploadDao.java index 06336ae04cc..0defb36ebb5 100755 --- a/engine/schema/src/com/cloud/storage/dao/UploadDao.java +++ b/engine/schema/src/com/cloud/storage/dao/UploadDao.java @@ -24,13 +24,12 @@ import com.cloud.storage.Upload.Type; import com.cloud.storage.Upload.Mode; import com.cloud.utils.db.GenericDao; -public interface UploadDao extends GenericDao { +public interface UploadDao extends GenericDao { - List listByTypeUploadStatus(long typeId, Type type, - Status uploadState); + List listByTypeUploadStatus(long typeId, Type type, Status uploadState); - List listByHostAndUploadStatus(long sserverId, Status uploadInProgress); - - List listByModeAndStatus(Mode mode, Status uploadState); + List listByHostAndUploadStatus(long sserverId, Status uploadInProgress); + + List listByModeAndStatus(Mode mode, Status uploadState); } diff --git a/engine/schema/src/com/cloud/storage/dao/UploadDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/UploadDaoImpl.java index 4c6da393eb3..8e112bff17f 100755 --- a/engine/schema/src/com/cloud/storage/dao/UploadDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/UploadDaoImpl.java @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. package com.cloud.storage.dao; + import java.util.List; import javax.ejb.Local; @@ -29,64 +30,64 @@ import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @Component -@Local(value={UploadDao.class}) +@Local(value = { UploadDao.class }) public class UploadDaoImpl extends GenericDaoBase implements UploadDao { - public static final Logger s_logger = Logger.getLogger(UploadDaoImpl.class.getName()); - protected final SearchBuilder typeUploadStatusSearch; - protected final SearchBuilder typeHostAndUploadStatusSearch; - protected final SearchBuilder typeModeAndStatusSearch; - - protected static final String UPDATE_UPLOAD_INFO = - "UPDATE upload SET upload_state = ?, upload_pct= ?, last_updated = ? " - + ", upload_error_str = ?, upload_job_id = ? " - + "WHERE host_id = ? and type_id = ? and type = ?"; - - protected static final String UPLOADS_STATE_DC= - "SELECT * FROM upload t, host h where t.host_id = h.id and h.data_center_id=? " - + " and t.type_id=? and t.upload_state = ?" ; - - - public UploadDaoImpl() { - typeUploadStatusSearch = createSearchBuilder(); - typeUploadStatusSearch.and("type_id", typeUploadStatusSearch.entity().getTypeId(), SearchCriteria.Op.EQ); - typeUploadStatusSearch.and("upload_state", typeUploadStatusSearch.entity().getUploadState(), SearchCriteria.Op.EQ); - typeUploadStatusSearch.and("type", typeUploadStatusSearch.entity().getType(), SearchCriteria.Op.EQ); - typeUploadStatusSearch.done(); - - typeHostAndUploadStatusSearch = createSearchBuilder(); - typeHostAndUploadStatusSearch.and("host_id", typeHostAndUploadStatusSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); - typeHostAndUploadStatusSearch.and("upload_state", typeHostAndUploadStatusSearch.entity().getUploadState(), SearchCriteria.Op.EQ); - typeHostAndUploadStatusSearch.done(); - - typeModeAndStatusSearch = createSearchBuilder(); - typeModeAndStatusSearch.and("mode", typeModeAndStatusSearch.entity().getMode(), SearchCriteria.Op.EQ); - typeModeAndStatusSearch.and("upload_state", typeModeAndStatusSearch.entity().getUploadState(), SearchCriteria.Op.EQ); - typeModeAndStatusSearch.done(); - - } - - @Override - public List listByTypeUploadStatus(long typeId, UploadVO.Type type, UploadVO.Status uploadState) { - SearchCriteria sc = typeUploadStatusSearch.create(); - sc.setParameters("type_id", typeId); - sc.setParameters("type", type); - sc.setParameters("upload_state", uploadState.toString()); - return listBy(sc); - } - - @Override - public List listByHostAndUploadStatus(long sserverId, Status uploadState){ + public static final Logger s_logger = Logger.getLogger(UploadDaoImpl.class.getName()); + protected final SearchBuilder typeUploadStatusSearch; + protected final SearchBuilder typeHostAndUploadStatusSearch; + protected final SearchBuilder typeModeAndStatusSearch; + + protected static final String UPDATE_UPLOAD_INFO = "UPDATE upload SET upload_state = ?, upload_pct= ?, last_updated = ? " + + ", upload_error_str = ?, upload_job_id = ? " + "WHERE host_id = ? and type_id = ? and type = ?"; + + protected static final String UPLOADS_STATE_DC = "SELECT * FROM upload t, host h where t.host_id = h.id and h.data_center_id=? " + + " and t.type_id=? and t.upload_state = ?"; + + public UploadDaoImpl() { + typeUploadStatusSearch = createSearchBuilder(); + typeUploadStatusSearch.and("type_id", typeUploadStatusSearch.entity().getTypeId(), SearchCriteria.Op.EQ); + typeUploadStatusSearch.and("upload_state", typeUploadStatusSearch.entity().getUploadState(), + SearchCriteria.Op.EQ); + typeUploadStatusSearch.and("type", typeUploadStatusSearch.entity().getType(), SearchCriteria.Op.EQ); + typeUploadStatusSearch.done(); + + typeHostAndUploadStatusSearch = createSearchBuilder(); + typeHostAndUploadStatusSearch.and("host_id", typeHostAndUploadStatusSearch.entity().getDataStoreId(), + SearchCriteria.Op.EQ); + typeHostAndUploadStatusSearch.and("upload_state", typeHostAndUploadStatusSearch.entity().getUploadState(), + SearchCriteria.Op.EQ); + typeHostAndUploadStatusSearch.done(); + + typeModeAndStatusSearch = createSearchBuilder(); + typeModeAndStatusSearch.and("mode", typeModeAndStatusSearch.entity().getMode(), SearchCriteria.Op.EQ); + typeModeAndStatusSearch.and("upload_state", typeModeAndStatusSearch.entity().getUploadState(), + SearchCriteria.Op.EQ); + typeModeAndStatusSearch.done(); + + } + + @Override + public List listByTypeUploadStatus(long typeId, UploadVO.Type type, UploadVO.Status uploadState) { + SearchCriteria sc = typeUploadStatusSearch.create(); + sc.setParameters("type_id", typeId); + sc.setParameters("type", type); + sc.setParameters("upload_state", uploadState.toString()); + return listBy(sc); + } + + @Override + public List listByHostAndUploadStatus(long sserverId, Status uploadState) { SearchCriteria sc = typeHostAndUploadStatusSearch.create(); sc.setParameters("host_id", sserverId); sc.setParameters("upload_state", uploadState.toString()); return listBy(sc); - } - - @Override - public List listByModeAndStatus(Mode mode, Status uploadState){ - SearchCriteria sc = typeModeAndStatusSearch.create(); - sc.setParameters("mode", mode.toString()); - sc.setParameters("upload_state", uploadState.toString()); - return listBy(sc); - } + } + + @Override + public List listByModeAndStatus(Mode mode, Status uploadState) { + SearchCriteria sc = typeModeAndStatusSearch.create(); + sc.setParameters("mode", mode.toString()); + sc.setParameters("upload_state", uploadState.toString()); + return listBy(sc); + } } \ No newline at end of file diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java index b4376fd550e..b80ad3a01bf 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java @@ -30,36 +30,49 @@ import com.cloud.utils.fsm.StateDao; /* * Data Access Object for vm_templates table */ -public interface VMTemplateDao extends GenericDao, StateDao { +public interface VMTemplateDao extends GenericDao, + StateDao { + public List listByPublic(); - public List listByPublic(); - public VMTemplateVO findByName(String templateName); - public VMTemplateVO findByTemplateName(String templateName); + public VMTemplateVO findByName(String templateName); - //public void update(VMTemplateVO template); + public VMTemplateVO findByTemplateName(String templateName); + // public void update(VMTemplateVO template); - public List listAllSystemVMTemplates(); + public List listAllSystemVMTemplates(); - public List listDefaultBuiltinTemplates(); - public String getRoutingTemplateUniqueName(); - public List findIsosByIdAndPath(Long domainId, Long accountId, String path); - public List listReadyTemplates(); - public List listByAccountId(long accountId); + public List listDefaultBuiltinTemplates(); - public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); - public List listAllInZone(long dataCenterId); - public List listAllActive(); + public String getRoutingTemplateUniqueName(); + + public List findIsosByIdAndPath(Long domainId, Long accountId, String path); + + public List listReadyTemplates(); + + public List listByAccountId(long accountId); + + public long addTemplateToZone(VMTemplateVO tmplt, long zoneId); + + public List listAllInZone(long dataCenterId); + + public List listAllActive(); public List listByHypervisorType(List hyperTypes); - public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags); - public List userIsoSearch(boolean listRemoved); + + public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags); + + public List userIsoSearch(boolean listRemoved); + VMTemplateVO findSystemVMTemplate(long zoneId); + VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType); VMTemplateVO findRoutingTemplate(HypervisorType type, String templateName); + List listPrivateTemplatesByHost(Long hostId); + public Long countTemplatesForAccount(long accountId); List findTemplatesToSyncToS3(); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 7bd8b6d88dc..21dd0adce4e 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; + import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -61,7 +62,7 @@ import com.cloud.utils.db.UpdateBuilder; import com.cloud.utils.exception.CloudRuntimeException; @Component -@Local(value={VMTemplateDao.class}) +@Local(value = { VMTemplateDao.class }) public class VMTemplateDaoImpl extends GenericDaoBase implements VMTemplateDao { private static final Logger s_logger = Logger.getLogger(VMTemplateDaoImpl.class); @@ -71,35 +72,20 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem VMTemplateDetailsDao _templateDetailsDao; @Inject - ConfigurationDao _configDao; + ConfigurationDao _configDao; @Inject - HostDao _hostDao; + HostDao _hostDao; @Inject DomainDao _domainDao; @Inject DataCenterDao _dcDao; - /* TODO: these direct sql should go away with recent QueryService refactoring to handle listTemplatesCmd. Keep here just for - * potential bug reference. - private final String SELECT_TEMPLATE_HOST_REF = "SELECT t.id, h.data_center_id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + - "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; - - private final String SELECT_TEMPLATE_ZONE_REF = "SELECT t.id, tzr.zone_id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " + - "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t INNER JOIN template_zone_ref tzr on (t.id = tzr.template_id) "; - - private final String SELECT_TEMPLATE_SWIFT_REF = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " - + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; - - private final String SELECT_TEMPLATE_S3_REF = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, " - + "t.checksum, t.display_text, t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type FROM vm_template t"; - */ - - private static final String SELECT_S3_CANDIDATE_TEMPLATES = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, " + - "t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, t.checksum, t.display_text, " + - "t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type " + - "FROM vm_template t JOIN template_host_ref r ON t.id=r.template_id JOIN host h ON h.id=r.host_id " + - "WHERE t.hypervisor_type IN (SELECT hypervisor_type FROM host) AND r.download_state = 'DOWNLOADED' AND " + - "r.template_id NOT IN (SELECT template_id FROM template_s3_ref) AND r.destroyed = 0 AND t.type <> 'PERHOST'"; + private static final String SELECT_S3_CANDIDATE_TEMPLATES = "SELECT t.id, t.unique_name, t.name, t.public, t.featured, " + + "t.type, t.hvm, t.bits, t.url, t.format, t.created, t.account_id, t.checksum, t.display_text, " + + "t.enable_password, t.guest_os_id, t.bootable, t.prepopulate, t.cross_zones, t.hypervisor_type " + + "FROM vm_template t JOIN template_host_ref r ON t.id=r.template_id JOIN host h ON h.id=r.host_id " + + "WHERE t.hypervisor_type IN (SELECT hypervisor_type FROM host) AND r.download_state = 'DOWNLOADED' AND " + + "r.template_id NOT IN (SELECT template_id FROM template_s3_ref) AND r.destroyed = 0 AND t.type <> 'PERHOST'"; protected SearchBuilder TemplateNameSearch; protected SearchBuilder UniqueNameSearch; @@ -118,8 +104,8 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private GenericSearchBuilder CountTemplatesByAccount; private SearchBuilder updateStateSearch; - @Inject ResourceTagDao _tagsDao; - + @Inject + ResourceTagDao _tagsDao; private String routerTmpltName; private String consoleProxyTmpltName; @@ -129,27 +115,27 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem @Override public List listByPublic() { - SearchCriteria sc = PublicSearch.create(); - sc.setParameters("public", 1); - return listBy(sc); - } - - @Override - public VMTemplateVO findByName(String templateName) { - SearchCriteria sc = UniqueNameSearch.create(); - sc.setParameters("uniqueName", templateName); - return findOneIncludingRemovedBy(sc); - } - - @Override - public VMTemplateVO findByTemplateName(String templateName) { - SearchCriteria sc = NameSearch.create(); - sc.setParameters("name", templateName); - return findOneIncludingRemovedBy(sc); - } + SearchCriteria sc = PublicSearch.create(); + sc.setParameters("public", 1); + return listBy(sc); + } @Override - public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags){ + public VMTemplateVO findByName(String templateName) { + SearchCriteria sc = UniqueNameSearch.create(); + sc.setParameters("uniqueName", templateName); + return findOneIncludingRemovedBy(sc); + } + + @Override + public VMTemplateVO findByTemplateName(String templateName) { + SearchCriteria sc = NameSearch.create(); + sc.setParameters("name", templateName); + return findOneIncludingRemovedBy(sc); + } + + @Override + public List publicIsoSearch(Boolean bootable, boolean listRemoved, Map tags) { SearchBuilder sb = null; if (tags == null || tags.isEmpty()) { @@ -163,30 +149,31 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sb.and("removed", sb.entity().getRemoved(), SearchCriteria.Op.EQ); SearchBuilder tagSearch = _tagsDao.createSearchBuilder(); - for (int count=0; count < tags.size(); count++) { + for (int count = 0; count < tags.size(); count++) { tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); tagSearch.cp(); } tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), + JoinBuilder.JoinType.INNER); } SearchCriteria sc = sb.create(); - sc.setParameters("public", 1); - sc.setParameters("format", "ISO"); - sc.setParameters("type", TemplateType.PERHOST.toString()); - if (bootable != null) { - sc.setParameters("bootable", bootable); - } + sc.setParameters("public", 1); + sc.setParameters("format", "ISO"); + sc.setParameters("type", TemplateType.PERHOST.toString()); + if (bootable != null) { + sc.setParameters("bootable", bootable); + } - if (!listRemoved) { - sc.setParameters("removed", (Object)null); - } + if (!listRemoved) { + sc.setParameters("removed", (Object) null); + } - if (tags != null && !tags.isEmpty()) { + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.ISO.toString()); for (String key : tags.keySet()) { @@ -200,7 +187,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } @Override - public List userIsoSearch(boolean listRemoved){ + public List userIsoSearch(boolean listRemoved) { SearchBuilder sb = null; sb = UserIsoSearch; @@ -210,25 +197,26 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem sc.setParameters("type", TemplateType.USER.toString()); if (!listRemoved) { - sc.setParameters("removed", (Object)null); + sc.setParameters("removed", (Object) null); } return listBy(sc); } - @Override - public List listAllSystemVMTemplates() { - SearchCriteria sc = tmpltTypeSearch.create(); - sc.setParameters("templateType", Storage.TemplateType.SYSTEM); - Filter filter = new Filter(VMTemplateVO.class, "id", false, null, null); - return listBy(sc, filter); - } + @Override + public List listAllSystemVMTemplates() { + SearchCriteria sc = tmpltTypeSearch.create(); + sc.setParameters("templateType", Storage.TemplateType.SYSTEM); + + Filter filter = new Filter(VMTemplateVO.class, "id", false, null, null); + return listBy(sc, filter); + } @Override public List listPrivateTemplatesByHost(Long hostId) { String sql = "select * from template_host_ref as thr INNER JOIN vm_template as t ON t.id=thr.template_id " - + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.removed is NULL"; + + "where thr.host_id=? and t.public=0 and t.featured=0 and t.type='USER' and t.removed is NULL"; List l = new ArrayList(); @@ -248,136 +236,138 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return l; } - @Override - public List listReadyTemplates() { - SearchCriteria sc = createSearchCriteria(); - sc.addAnd("ready", SearchCriteria.Op.EQ, true); - sc.addAnd("format", SearchCriteria.Op.NEQ, Storage.ImageFormat.ISO); - return listIncludingRemovedBy(sc); - } + @Override + public List listReadyTemplates() { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("ready", SearchCriteria.Op.EQ, true); + sc.addAnd("format", SearchCriteria.Op.NEQ, Storage.ImageFormat.ISO); + return listIncludingRemovedBy(sc); + } - @Override - public List findIsosByIdAndPath(Long domainId, Long accountId, String path) { - SearchCriteria sc = createSearchCriteria(); - sc.addAnd("iso", SearchCriteria.Op.EQ, true); - if (domainId != null) { + @Override + public List findIsosByIdAndPath(Long domainId, Long accountId, String path) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("iso", SearchCriteria.Op.EQ, true); + if (domainId != null) { sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId); } - if (accountId != null) { + if (accountId != null) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); } - if (path != null) { + if (path != null) { sc.addAnd("path", SearchCriteria.Op.EQ, path); } - return listIncludingRemovedBy(sc); - } + return listIncludingRemovedBy(sc); + } - @Override - public List listByAccountId(long accountId) { + @Override + public List listByAccountId(long accountId) { SearchCriteria sc = AccountIdSearch.create(); sc.setParameters("accountId", accountId); return listBy(sc); - } + } - @Override + @Override public List listByHypervisorType(List hyperTypes) { - SearchCriteria sc = createSearchCriteria(); + SearchCriteria sc = createSearchCriteria(); hyperTypes.add(HypervisorType.None); sc.addAnd("hypervisorType", SearchCriteria.Op.IN, hyperTypes.toArray()); - return listBy(sc); - } + return listBy(sc); + } - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - boolean result = super.configure(name, params); + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + boolean result = super.configure(name, params); - PublicSearch = createSearchBuilder(); - PublicSearch.and("public", PublicSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); + PublicSearch = createSearchBuilder(); + PublicSearch.and("public", PublicSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); - routerTmpltName = (String)params.get("routing.uniquename"); + routerTmpltName = (String) params.get("routing.uniquename"); - s_logger.debug("Found parameter routing unique name " + routerTmpltName); - if (routerTmpltName==null) { - routerTmpltName="routing"; - } + s_logger.debug("Found parameter routing unique name " + routerTmpltName); + if (routerTmpltName == null) { + routerTmpltName = "routing"; + } - consoleProxyTmpltName = (String)params.get("consoleproxy.uniquename"); - if(consoleProxyTmpltName == null) { + consoleProxyTmpltName = (String) params.get("consoleproxy.uniquename"); + if (consoleProxyTmpltName == null) { consoleProxyTmpltName = "routing"; } - if(s_logger.isDebugEnabled()) { + if (s_logger.isDebugEnabled()) { s_logger.debug("Use console proxy template : " + consoleProxyTmpltName); } - UniqueNameSearch = createSearchBuilder(); - UniqueNameSearch.and("uniqueName", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ); - NameSearch = createSearchBuilder(); - NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ); + UniqueNameSearch = createSearchBuilder(); + UniqueNameSearch.and("uniqueName", UniqueNameSearch.entity().getUniqueName(), SearchCriteria.Op.EQ); + NameSearch = createSearchBuilder(); + NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ); - NameAccountIdSearch = createSearchBuilder(); - NameAccountIdSearch.and("name", NameAccountIdSearch.entity().getName(), SearchCriteria.Op.EQ); - NameAccountIdSearch.and("accountId", NameAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + NameAccountIdSearch = createSearchBuilder(); + NameAccountIdSearch.and("name", NameAccountIdSearch.entity().getName(), SearchCriteria.Op.EQ); + NameAccountIdSearch.and("accountId", NameAccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); - PublicIsoSearch = createSearchBuilder(); - PublicIsoSearch.and("public", PublicIsoSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); - PublicIsoSearch.and("format", PublicIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); - PublicIsoSearch.and("type", PublicIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); - PublicIsoSearch.and("bootable", PublicIsoSearch.entity().isBootable(), SearchCriteria.Op.EQ); - PublicIsoSearch.and("removed", PublicIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); + PublicIsoSearch = createSearchBuilder(); + PublicIsoSearch.and("public", PublicIsoSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); + PublicIsoSearch.and("format", PublicIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); + PublicIsoSearch.and("type", PublicIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + PublicIsoSearch.and("bootable", PublicIsoSearch.entity().isBootable(), SearchCriteria.Op.EQ); + PublicIsoSearch.and("removed", PublicIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); - UserIsoSearch = createSearchBuilder(); - UserIsoSearch.and("format", UserIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); - UserIsoSearch.and("type", UserIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); - UserIsoSearch.and("removed", UserIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); + UserIsoSearch = createSearchBuilder(); + UserIsoSearch.and("format", UserIsoSearch.entity().getFormat(), SearchCriteria.Op.EQ); + UserIsoSearch.and("type", UserIsoSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + UserIsoSearch.and("removed", UserIsoSearch.entity().getRemoved(), SearchCriteria.Op.EQ); - tmpltTypeHyperSearch = createSearchBuilder(); - tmpltTypeHyperSearch.and("templateType", tmpltTypeHyperSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); - SearchBuilder hostHyperSearch = _hostDao.createSearchBuilder(); - hostHyperSearch.and("type", hostHyperSearch.entity().getType(), SearchCriteria.Op.EQ); - hostHyperSearch.and("zoneId", hostHyperSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - hostHyperSearch.groupBy(hostHyperSearch.entity().getHypervisorType()); + tmpltTypeHyperSearch = createSearchBuilder(); + tmpltTypeHyperSearch.and("templateType", tmpltTypeHyperSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + SearchBuilder hostHyperSearch = _hostDao.createSearchBuilder(); + hostHyperSearch.and("type", hostHyperSearch.entity().getType(), SearchCriteria.Op.EQ); + hostHyperSearch.and("zoneId", hostHyperSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + hostHyperSearch.groupBy(hostHyperSearch.entity().getHypervisorType()); - tmpltTypeHyperSearch.join("tmplHyper", hostHyperSearch, hostHyperSearch.entity().getHypervisorType(), tmpltTypeHyperSearch.entity().getHypervisorType(), JoinBuilder.JoinType.INNER); - hostHyperSearch.done(); - tmpltTypeHyperSearch.done(); + tmpltTypeHyperSearch.join("tmplHyper", hostHyperSearch, hostHyperSearch.entity().getHypervisorType(), + tmpltTypeHyperSearch.entity().getHypervisorType(), JoinBuilder.JoinType.INNER); + hostHyperSearch.done(); + tmpltTypeHyperSearch.done(); - tmpltTypeHyperSearch2 = createSearchBuilder(); - tmpltTypeHyperSearch2.and("templateType", tmpltTypeHyperSearch2.entity().getTemplateType(), SearchCriteria.Op.EQ); - tmpltTypeHyperSearch2.and("hypervisorType", tmpltTypeHyperSearch2.entity().getHypervisorType(), SearchCriteria.Op.EQ); + tmpltTypeHyperSearch2 = createSearchBuilder(); + tmpltTypeHyperSearch2.and("templateType", tmpltTypeHyperSearch2.entity().getTemplateType(), + SearchCriteria.Op.EQ); + tmpltTypeHyperSearch2.and("hypervisorType", tmpltTypeHyperSearch2.entity().getHypervisorType(), + SearchCriteria.Op.EQ); tmpltTypeHyperSearch2.and("templateName", tmpltTypeHyperSearch2.entity().getName(), SearchCriteria.Op.EQ); - - tmpltTypeSearch = createSearchBuilder(); + tmpltTypeSearch = createSearchBuilder(); tmpltTypeSearch.and("removed", tmpltTypeSearch.entity().getRemoved(), SearchCriteria.Op.NULL); - tmpltTypeSearch.and("templateType", tmpltTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); + tmpltTypeSearch.and("templateType", tmpltTypeSearch.entity().getTemplateType(), SearchCriteria.Op.EQ); - AccountIdSearch = createSearchBuilder(); - AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); + AccountIdSearch = createSearchBuilder(); + AccountIdSearch.and("accountId", AccountIdSearch.entity().getAccountId(), SearchCriteria.Op.EQ); AccountIdSearch.and("publicTemplate", AccountIdSearch.entity().isPublicTemplate(), SearchCriteria.Op.EQ); - AccountIdSearch.done(); + AccountIdSearch.done(); - SearchBuilder tmpltZoneSearch = _templateZoneDao.createSearchBuilder(); - tmpltZoneSearch.and("removed", tmpltZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); - tmpltZoneSearch.and("zoneId", tmpltZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); + SearchBuilder tmpltZoneSearch = _templateZoneDao.createSearchBuilder(); + tmpltZoneSearch.and("removed", tmpltZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + tmpltZoneSearch.and("zoneId", tmpltZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); - TmpltsInZoneSearch = createSearchBuilder(); - TmpltsInZoneSearch.and("removed", TmpltsInZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); - TmpltsInZoneSearch.and().op("avoidtype", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NEQ); - TmpltsInZoneSearch.or("templateType", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NULL); - TmpltsInZoneSearch.cp(); - TmpltsInZoneSearch.join("tmpltzone", tmpltZoneSearch, tmpltZoneSearch.entity().getTemplateId(), TmpltsInZoneSearch.entity().getId(), JoinBuilder.JoinType.INNER); - tmpltZoneSearch.done(); - TmpltsInZoneSearch.done(); + TmpltsInZoneSearch = createSearchBuilder(); + TmpltsInZoneSearch.and("removed", TmpltsInZoneSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + TmpltsInZoneSearch.and().op("avoidtype", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NEQ); + TmpltsInZoneSearch.or("templateType", TmpltsInZoneSearch.entity().getTemplateType(), SearchCriteria.Op.NULL); + TmpltsInZoneSearch.cp(); + TmpltsInZoneSearch.join("tmpltzone", tmpltZoneSearch, tmpltZoneSearch.entity().getTemplateId(), + TmpltsInZoneSearch.entity().getId(), JoinBuilder.JoinType.INNER); + tmpltZoneSearch.done(); + TmpltsInZoneSearch.done(); ActiveTmpltSearch = createSearchBuilder(); ActiveTmpltSearch.and("removed", ActiveTmpltSearch.entity().getRemoved(), SearchCriteria.Op.NULL); - - CountTemplatesByAccount = createSearchBuilder(Long.class); - CountTemplatesByAccount.select(null, Func.COUNT, null); - CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); - CountTemplatesByAccount.and("removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); - CountTemplatesByAccount.done(); + CountTemplatesByAccount = createSearchBuilder(Long.class); + CountTemplatesByAccount.select(null, Func.COUNT, null); + CountTemplatesByAccount.and("account", CountTemplatesByAccount.entity().getAccountId(), SearchCriteria.Op.EQ); + CountTemplatesByAccount.and("removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); + CountTemplatesByAccount.done(); updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); @@ -385,543 +375,388 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); updateStateSearch.done(); - return result; - } - - @Override - public String getRoutingTemplateUniqueName() { - return routerTmpltName; - } - - /* - @Override - public Set> searchSwiftTemplates(String name, String keyword, TemplateFilter templateFilter, boolean isIso, List hypers, Boolean bootable, DomainVO domain, - Long pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr, List permittedAccounts, Account caller, Map tags) { - - StringBuilder builder = new StringBuilder(); - if (!permittedAccounts.isEmpty()) { - for (Account permittedAccount : permittedAccounts) { - builder.append(permittedAccount.getAccountId() + ","); - } - } - - String permittedAccountsStr = builder.toString(); - - if (permittedAccountsStr.length() > 0) { - // chop the "," off - permittedAccountsStr = permittedAccountsStr.substring(0, permittedAccountsStr.length() - 1); - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - Set> templateZonePairList = new HashSet>(); - PreparedStatement pstmt = null; - ResultSet rs = null; - String sql = SELECT_TEMPLATE_SWIFT_REF; - try { - String joinClause = ""; - String whereClause = " WHERE t.removed IS NULL"; - - if (isIso) { - whereClause += " AND t.format = 'ISO'"; - if (!hyperType.equals(HypervisorType.None)) { - joinClause = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "; - whereClause += " AND goh.hypervisor_type = '" + hyperType.toString() + "'"; - } - } else { - whereClause += " AND t.format <> 'ISO'"; - if (hypers.isEmpty()) { - return templateZonePairList; - } else { - StringBuilder relatedHypers = new StringBuilder(); - for (HypervisorType hyper : hypers) { - relatedHypers.append("'"); - relatedHypers.append(hyper.toString()); - relatedHypers.append("'"); - relatedHypers.append(","); - } - relatedHypers.setLength(relatedHypers.length() - 1); - whereClause += " AND t.hypervisor_type IN (" + relatedHypers + ")"; - } - } - joinClause += " INNER JOIN template_swift_ref tsr on (t.id = tsr.template_id)"; - if (keyword != null) { - whereClause += " AND t.name LIKE \"%" + keyword + "%\""; - } else if (name != null) { - whereClause += " AND t.name LIKE \"%" + name + "%\""; - } - - if (bootable != null) { - whereClause += " AND t.bootable = " + bootable; - } - - if (!showDomr) { - whereClause += " AND t.type != '" + Storage.TemplateType.SYSTEM.toString() + "'"; - } - - if (templateFilter == TemplateFilter.featured) { - whereClause += " AND t.public = 1 AND t.featured = 1"; - } else if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - joinClause += " INNER JOIN account a on (t.account_id = a.id) INNER JOIN domain d on (a.domain_id = d.id)"; - whereClause += " AND d.path LIKE '" + domain.getPath() + "%'"; - } else { - whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; - } - } else if ((templateFilter == TemplateFilter.shared || templateFilter == TemplateFilter.sharedexecutable) && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { - joinClause += " LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE" + " (t.account_id IN (" + permittedAccountsStr + ") OR" + " lp.account_id IN (" - + permittedAccountsStr + "))"; - } else { - joinClause += " INNER JOIN account a on (t.account_id = a.id) "; - } - } else if (templateFilter == TemplateFilter.executable && !permittedAccounts.isEmpty()) { - whereClause += " AND (t.public = 1 OR t.account_id IN (" + permittedAccountsStr + "))"; - } else if (templateFilter == TemplateFilter.community) { - whereClause += " AND t.public = 1 AND t.featured = 0"; - } else if (templateFilter == TemplateFilter.all && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { - } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - return templateZonePairList; - } - - sql += joinClause + whereClause + getOrderByLimit(pageSize, startIndex); - pstmt = txn.prepareStatement(sql); - rs = pstmt.executeQuery(); - while (rs.next()) { - Pair templateZonePair = new Pair(rs.getLong(1), -1L); - templateZonePairList.add(templateZonePair); - } - - } catch (Exception e) { - s_logger.warn("Error listing templates", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - txn.commit(); - } catch (SQLException sqle) { - s_logger.warn("Error in cleaning up", sqle); - } - } - - return templateZonePairList; + return result; } + @Override + public String getRoutingTemplateUniqueName() { + return routerTmpltName; + } - @Override - public Set> searchTemplates(String name, String keyword, TemplateFilter templateFilter, - boolean isIso, List hypers, Boolean bootable, DomainVO domain, Long pageSize, Long startIndex, - Long zoneId, HypervisorType hyperType, boolean onlyReady, boolean showDomr,List permittedAccounts, - Account caller, ListProjectResourcesCriteria listProjectResourcesCriteria, Map tags, String zoneType) { - StringBuilder builder = new StringBuilder(); - if (!permittedAccounts.isEmpty()) { - for (Account permittedAccount : permittedAccounts) { - builder.append(permittedAccount.getAccountId() + ","); - } - } + /* + * @Override public Set> searchSwiftTemplates(String name, + * String keyword, TemplateFilter templateFilter, boolean isIso, + * List hypers, Boolean bootable, DomainVO domain, Long + * pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean + * onlyReady, boolean showDomr, List permittedAccounts, Account + * caller, Map tags) { + * + * StringBuilder builder = new StringBuilder(); if + * (!permittedAccounts.isEmpty()) { for (Account permittedAccount : + * permittedAccounts) { builder.append(permittedAccount.getAccountId() + + * ","); } } + * + * String permittedAccountsStr = builder.toString(); + * + * if (permittedAccountsStr.length() > 0) { // chop the "," off + * permittedAccountsStr = permittedAccountsStr.substring(0, + * permittedAccountsStr.length() - 1); } + * + * Transaction txn = Transaction.currentTxn(); txn.start(); + * + * Set> templateZonePairList = new HashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; String sql + * = SELECT_TEMPLATE_SWIFT_REF; try { String joinClause = ""; String + * whereClause = " WHERE t.removed IS NULL"; + * + * if (isIso) { whereClause += " AND t.format = 'ISO'"; if + * (!hyperType.equals(HypervisorType.None)) { joinClause = + * " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) " + * ; whereClause += " AND goh.hypervisor_type = '" + hyperType.toString() + + * "'"; } } else { whereClause += " AND t.format <> 'ISO'"; if + * (hypers.isEmpty()) { return templateZonePairList; } else { StringBuilder + * relatedHypers = new StringBuilder(); for (HypervisorType hyper : hypers) + * { relatedHypers.append("'"); relatedHypers.append(hyper.toString()); + * relatedHypers.append("'"); relatedHypers.append(","); } + * relatedHypers.setLength(relatedHypers.length() - 1); whereClause += + * " AND t.hypervisor_type IN (" + relatedHypers + ")"; } } joinClause += + * " INNER JOIN template_swift_ref tsr on (t.id = tsr.template_id)"; if + * (keyword != null) { whereClause += " AND t.name LIKE \"%" + keyword + + * "%\""; } else if (name != null) { whereClause += " AND t.name LIKE \"%" + + * name + "%\""; } + * + * if (bootable != null) { whereClause += " AND t.bootable = " + bootable; } + * + * if (!showDomr) { whereClause += " AND t.type != '" + + * Storage.TemplateType.SYSTEM.toString() + "'"; } + * + * if (templateFilter == TemplateFilter.featured) { whereClause += + * " AND t.public = 1 AND t.featured = 1"; } else if ((templateFilter == + * TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) + * && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { if (caller.getType() + * == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == + * Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { joinClause += + * " INNER JOIN account a on (t.account_id = a.id) INNER JOIN domain d on (a.domain_id = d.id)" + * ; whereClause += " AND d.path LIKE '" + domain.getPath() + "%'"; } else + * { whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; } + * } else if ((templateFilter == TemplateFilter.shared || templateFilter == + * TemplateFilter.sharedexecutable) && caller.getType() != + * Account.ACCOUNT_TYPE_ADMIN) { if (caller.getType() == + * Account.ACCOUNT_TYPE_NORMAL) { joinClause += + * " LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE" + + * " (t.account_id IN (" + permittedAccountsStr + ") OR" + + * " lp.account_id IN (" + permittedAccountsStr + "))"; } else { joinClause + * += " INNER JOIN account a on (t.account_id = a.id) "; } } else if + * (templateFilter == TemplateFilter.executable && + * !permittedAccounts.isEmpty()) { whereClause += + * " AND (t.public = 1 OR t.account_id IN (" + permittedAccountsStr + "))"; + * } else if (templateFilter == TemplateFilter.community) { whereClause += + * " AND t.public = 1 AND t.featured = 0"; } else if (templateFilter == + * TemplateFilter.all && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { } + * else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { return + * templateZonePairList; } + * + * sql += joinClause + whereClause + getOrderByLimit(pageSize, startIndex); + * pstmt = txn.prepareStatement(sql); rs = pstmt.executeQuery(); while + * (rs.next()) { Pair templateZonePair = new Pair(rs.getLong(1), -1L); templateZonePairList.add(templateZonePair); } + * + * } catch (Exception e) { s_logger.warn("Error listing templates", e); } + * finally { try { if (rs != null) { rs.close(); } if (pstmt != null) { + * pstmt.close(); } txn.commit(); } catch (SQLException sqle) { + * s_logger.warn("Error in cleaning up", sqle); } } + * + * return templateZonePairList; } + * + * + * @Override public Set> searchTemplates(String name, + * String keyword, TemplateFilter templateFilter, boolean isIso, + * List hypers, Boolean bootable, DomainVO domain, Long + * pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean + * onlyReady, boolean showDomr,List permittedAccounts, Account + * caller, ListProjectResourcesCriteria listProjectResourcesCriteria, + * Map tags, String zoneType) { StringBuilder builder = new + * StringBuilder(); if (!permittedAccounts.isEmpty()) { for (Account + * permittedAccount : permittedAccounts) { + * builder.append(permittedAccount.getAccountId() + ","); } } + * + * String permittedAccountsStr = builder.toString(); + * + * if (permittedAccountsStr.length() > 0) { //chop the "," off + * permittedAccountsStr = permittedAccountsStr.substring(0, + * permittedAccountsStr.length()-1); } + * + * Transaction txn = Transaction.currentTxn(); txn.start(); + * + * // Use LinkedHashSet here to guarantee iteration order Set> templateZonePairList = new LinkedHashSet>(); + * PreparedStatement pstmt = null; ResultSet rs = null; StringBuilder + * relatedDomainIds = new StringBuilder(); String sql = + * SELECT_TEMPLATE_ZONE_REF; String groupByClause = ""; try { //short + * accountType; //String accountId = null; String guestOSJoin = ""; + * StringBuilder templateHostRefJoin = new StringBuilder(); String + * dataCenterJoin = "", lpjoin = ""; String tagsJoin = ""; + * + * if (isIso && !hyperType.equals(HypervisorType.None)) { guestOSJoin = + * " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) " + * ; } if (onlyReady){ templateHostRefJoin.append( + * " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)" + * ); sql = SELECT_TEMPLATE_HOST_REF; groupByClause = + * " GROUP BY t.id, h.data_center_id "; } if ((templateFilter == + * TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) + * { dataCenterJoin = + * " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } + * + * if (zoneType != null) { dataCenterJoin = + * " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)" + * ; dataCenterJoin += + * " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } + * + * if (templateFilter == TemplateFilter.sharedexecutable || templateFilter + * == TemplateFilter.shared ){ lpjoin = + * " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } + * + * if (tags != null && !tags.isEmpty()) { tagsJoin = + * " INNER JOIN resource_tags r ON t.id = r.resource_id "; } + * + * sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin + + * tagsJoin; String whereClause = ""; + * + * //All joins have to be made before we start setting the condition + * settings if ((listProjectResourcesCriteria == + * ListProjectResourcesCriteria.SkipProjectResources || + * (!permittedAccounts.isEmpty() && !(templateFilter == + * TemplateFilter.community || templateFilter == TemplateFilter.featured))) + * && !(caller.getType() != Account.ACCOUNT_TYPE_NORMAL && templateFilter == + * TemplateFilter.all)) { whereClause += + * " INNER JOIN account a on (t.account_id = a.id)"; if ((templateFilter == + * TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) + * && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || + * caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { + * whereClause += + * " INNER JOIN domain d on (a.domain_id = d.id) WHERE d.path LIKE '" + + * domain.getPath() + "%'"; if (listProjectResourcesCriteria == + * ListProjectResourcesCriteria.SkipProjectResources) { whereClause += + * " AND a.type != " + Account.ACCOUNT_TYPE_PROJECT; } } else if + * (listProjectResourcesCriteria == + * ListProjectResourcesCriteria.SkipProjectResources) { whereClause += + * " WHERE a.type != " + Account.ACCOUNT_TYPE_PROJECT; } } + * + * if (!permittedAccounts.isEmpty()) { for (Account account : + * permittedAccounts) { //accountType = account.getType(); //accountId = + * Long.toString(account.getId()); DomainVO accountDomain = + * _domainDao.findById(account.getDomainId()); + * + * // get all parent domain ID's all the way till root domain DomainVO + * domainTreeNode = accountDomain; while (true) { + * relatedDomainIds.append(domainTreeNode.getId()); + * relatedDomainIds.append(","); if (domainTreeNode.getParent() != null) { + * domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); } else + * { break; } } + * + * // get all child domain ID's if (isAdmin(account.getType()) ) { + * List allChildDomains = + * _domainDao.findAllChildren(accountDomain.getPath(), + * accountDomain.getId()); for (DomainVO childDomain : allChildDomains) { + * relatedDomainIds.append(childDomain.getId()); + * relatedDomainIds.append(","); } } + * relatedDomainIds.setLength(relatedDomainIds.length()-1); } } + * + * String attr = " AND "; if (whereClause.endsWith(" WHERE ")) { attr += + * " WHERE "; } + * + * if (!isIso) { if ( hypers.isEmpty() ) { return templateZonePairList; } + * else { StringBuilder relatedHypers = new StringBuilder(); for + * (HypervisorType hyper : hypers ) { relatedHypers.append("'"); + * relatedHypers.append(hyper.toString()); relatedHypers.append("'"); + * relatedHypers.append(","); } + * relatedHypers.setLength(relatedHypers.length()-1); whereClause += attr + + * " t.hypervisor_type IN (" + relatedHypers + ")"; } } + * + * if (!permittedAccounts.isEmpty() && !(templateFilter == + * TemplateFilter.featured || templateFilter == TemplateFilter.community || + * templateFilter == TemplateFilter.executable || templateFilter == + * TemplateFilter.shared || templateFilter == + * TemplateFilter.sharedexecutable) && !isAdmin(caller.getType()) ) { + * whereClause += attr + "t.account_id IN (" + permittedAccountsStr + ")"; } + * + * if (templateFilter == TemplateFilter.featured) { whereClause += attr + + * "t.public = 1 AND t.featured = 1"; if (!permittedAccounts.isEmpty()) { + * whereClause += attr + "(dc.domain_id IN (" + relatedDomainIds + + * ") OR dc.domain_id is NULL)"; } } else if (templateFilter == + * TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { + * whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; } + * else if (templateFilter == TemplateFilter.sharedexecutable || + * templateFilter == TemplateFilter.shared ) { whereClause += " AND " + + * " (t.account_id IN (" + permittedAccountsStr + ") OR" + + * " lp.account_id IN (" + permittedAccountsStr + "))"; } else if + * (templateFilter == TemplateFilter.executable && + * !permittedAccounts.isEmpty()) { whereClause += attr + + * "(t.public = 1 OR t.account_id IN (" + permittedAccountsStr + "))"; } + * else if (templateFilter == TemplateFilter.community) { whereClause += + * attr + "t.public = 1 AND t.featured = 0"; if + * (!permittedAccounts.isEmpty()) { whereClause += attr + + * "(dc.domain_id IN (" + relatedDomainIds + ") OR dc.domain_id is NULL)"; } + * } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && !isIso) { + * return templateZonePairList; } + * + * if (tags != null && !tags.isEmpty()) { whereClause += " AND ("; boolean + * first = true; for (String key : tags.keySet()) { if (!first) { + * whereClause += " OR "; } whereClause += "(r.key=\"" + key + + * "\" and r.value=\"" + tags.get(key) + "\")"; first = false; } whereClause + * += ")"; } + * + * if (whereClause.equals("")) { whereClause += " WHERE "; } else if + * (!whereClause.equals(" WHERE ")) { whereClause += " AND "; } + * + * sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, + * bootable, hyperType, zoneId, onlyReady, showDomr, zoneType) + + * groupByClause + getOrderByLimit(pageSize, startIndex); + * + * pstmt = txn.prepareStatement(sql); rs = pstmt.executeQuery(); + * + * while (rs.next()) { Pair templateZonePair = new Pair(rs.getLong(1), rs.getLong(2)); + * templateZonePairList.add(templateZonePair); } //for now, defaulting + * pageSize to a large val if null; may need to revisit post 2.2RC2 if(isIso + * && templateZonePairList.size() < (pageSize != null ? pageSize : 500) && + * templateFilter != TemplateFilter.community && !(templateFilter == + * TemplateFilter.self && !BaseCmd.isRootAdmin(caller.getType())) ){ + * //evaluates to true If root admin and filter=self + * + * List publicIsos = publicIsoSearch(bootable, false, tags); + * List userIsos = userIsoSearch(false); + * + * //Listing the ISOs according to the page size.Restricting the total no. + * of ISOs on a page //to be less than or equal to the pageSize parameter + * + * int i=0; + * + * if (startIndex > userIsos.size()) { i=(int) (startIndex - + * userIsos.size()); } + * + * for (; i < publicIsos.size(); i++) { if(templateZonePairList.size() >= + * pageSize){ break; } else { if (keyword != null && + * publicIsos.get(i).getName().contains(keyword)) { + * templateZonePairList.add(new Pair(publicIsos.get(i).getId(), + * null)); continue; } else if (name != null && + * publicIsos.get(i).getName().contains(name)) { + * templateZonePairList.add(new Pair(publicIsos.get(i).getId(), + * null)); continue; } else if (keyword == null && name == null){ + * templateZonePairList.add(new Pair(publicIsos.get(i).getId(), + * null)); } } } } } catch (Exception e) { + * s_logger.warn("Error listing templates", e); } finally { try { if (rs != + * null) { rs.close(); } if (pstmt != null) { pstmt.close(); } txn.commit(); + * } catch( SQLException sqle) { s_logger.warn("Error in cleaning up", + * sqle); } } + * + * return templateZonePairList; } + */ - String permittedAccountsStr = builder.toString(); + /* + * private String getExtrasWhere(TemplateFilter templateFilter, String name, + * String keyword, boolean isIso, Boolean bootable, HypervisorType + * hyperType, Long zoneId, boolean onlyReady, boolean showDomr, String + * zoneType) { String sql = ""; if (keyword != null) { sql += + * " t.name LIKE \"%" + keyword + "%\" AND"; } else if (name != null) { sql + * += " t.name LIKE \"%" + name + "%\" AND"; } + * + * if (isIso) { sql += " t.format = 'ISO'"; if + * (!hyperType.equals(HypervisorType.None)) { sql += + * " AND goh.hypervisor_type = '" + hyperType.toString() + "'"; } } else { + * sql += " t.format <> 'ISO'"; if (!hyperType.equals(HypervisorType.None)) + * { sql += " AND t.hypervisor_type = '" + hyperType.toString() + "'"; } } + * + * if (bootable != null) { sql += " AND t.bootable = " + bootable; } + * + * if (onlyReady){ sql += " AND thr.download_state = '" + * +Status.DOWNLOADED.toString() + "'" + " AND thr.destroyed=0 "; if (zoneId + * != null){ sql += " AND h.data_center_id = " +zoneId; } }else if (zoneId + * != null){ sql += " AND tzr.zone_id = " +zoneId+ + * " AND tzr.removed is null" ; }else{ sql += " AND tzr.removed is null "; } + * + * if (zoneType != null){ sql += " AND dc.networktype = '" + zoneType + "'"; + * } + * + * if (!showDomr){ sql += " AND t.type != '" + * +Storage.TemplateType.SYSTEM.toString() + "'"; } + * + * sql += " AND t.removed IS NULL"; + * + * return sql; } + * + * private String getOrderByLimit(Long pageSize, Long startIndex) { Boolean + * isAscending = + * Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); + * isAscending = (isAscending == null ? true : isAscending); + * + * String sql; if (isAscending) { sql = " ORDER BY t.sort_key ASC"; } else { + * sql = " ORDER BY t.sort_key DESC"; } + * + * if ((pageSize != null) && (startIndex != null)) { sql += " LIMIT " + + * startIndex.toString() + "," + pageSize.toString(); } return sql; } + */ - if (permittedAccountsStr.length() > 0) { - //chop the "," off - permittedAccountsStr = permittedAccountsStr.substring(0, permittedAccountsStr.length()-1); - } - - Transaction txn = Transaction.currentTxn(); + @SuppressWarnings("unchecked") + @Override + @DB + public long addTemplateToZone(VMTemplateVO tmplt, long zoneId) { + Transaction txn = Transaction.currentTxn(); txn.start(); - - // Use LinkedHashSet here to guarantee iteration order - Set> templateZonePairList = new LinkedHashSet>(); - PreparedStatement pstmt = null; - ResultSet rs = null; - StringBuilder relatedDomainIds = new StringBuilder(); - String sql = SELECT_TEMPLATE_ZONE_REF; - String groupByClause = ""; - try { - //short accountType; - //String accountId = null; - String guestOSJoin = ""; - StringBuilder templateHostRefJoin = new StringBuilder(); - String dataCenterJoin = "", lpjoin = ""; - String tagsJoin = ""; - - if (isIso && !hyperType.equals(HypervisorType.None)) { - guestOSJoin = " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "; - } - if (onlyReady){ - templateHostRefJoin.append(" INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)"); - sql = SELECT_TEMPLATE_HOST_REF; - groupByClause = " GROUP BY t.id, h.data_center_id "; - } - if ((templateFilter == TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) { - dataCenterJoin = " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; - } - - if (zoneType != null) { - dataCenterJoin = " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)"; - dataCenterJoin += " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; + VMTemplateVO tmplt2 = findById(tmplt.getId()); + if (tmplt2 == null) { + if (persist(tmplt) == null) { + throw new CloudRuntimeException("Failed to persist the template " + tmplt); } - - if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ){ - lpjoin = " INNER JOIN launch_permission lp ON t.id = lp.template_id "; - } - - if (tags != null && !tags.isEmpty()) { - tagsJoin = " INNER JOIN resource_tags r ON t.id = r.resource_id "; - } - - sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin + tagsJoin; - String whereClause = ""; - - //All joins have to be made before we start setting the condition settings - if ((listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources - || (!permittedAccounts.isEmpty() && !(templateFilter == TemplateFilter.community || templateFilter == TemplateFilter.featured))) && - !(caller.getType() != Account.ACCOUNT_TYPE_NORMAL && templateFilter == TemplateFilter.all)) { - whereClause += " INNER JOIN account a on (t.account_id = a.id)"; - if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) && (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN)) { - whereClause += " INNER JOIN domain d on (a.domain_id = d.id) WHERE d.path LIKE '" + domain.getPath() + "%'"; - if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { - whereClause += " AND a.type != " + Account.ACCOUNT_TYPE_PROJECT; - } - } else - if (listProjectResourcesCriteria == ListProjectResourcesCriteria.SkipProjectResources) { - whereClause += " WHERE a.type != " + Account.ACCOUNT_TYPE_PROJECT; - } - } - - if (!permittedAccounts.isEmpty()) { - for (Account account : permittedAccounts) { - //accountType = account.getType(); - //accountId = Long.toString(account.getId()); - DomainVO accountDomain = _domainDao.findById(account.getDomainId()); - - // get all parent domain ID's all the way till root domain - DomainVO domainTreeNode = accountDomain; - while (true) { - relatedDomainIds.append(domainTreeNode.getId()); - relatedDomainIds.append(","); - if (domainTreeNode.getParent() != null) { - domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); - } else { - break; - } - } - - // get all child domain ID's - if (isAdmin(account.getType()) ) { - List allChildDomains = _domainDao.findAllChildren(accountDomain.getPath(), accountDomain.getId()); - for (DomainVO childDomain : allChildDomains) { - relatedDomainIds.append(childDomain.getId()); - relatedDomainIds.append(","); - } - } - relatedDomainIds.setLength(relatedDomainIds.length()-1); - } + if (tmplt.getDetails() != null) { + _templateDetailsDao.persist(tmplt.getId(), tmplt.getDetails()); } - - String attr = " AND "; - if (whereClause.endsWith(" WHERE ")) { - attr += " WHERE "; - } - - if (!isIso) { - if ( hypers.isEmpty() ) { - return templateZonePairList; - } else { - StringBuilder relatedHypers = new StringBuilder(); - for (HypervisorType hyper : hypers ) { - relatedHypers.append("'"); - relatedHypers.append(hyper.toString()); - relatedHypers.append("'"); - relatedHypers.append(","); - } - relatedHypers.setLength(relatedHypers.length()-1); - whereClause += attr + " t.hypervisor_type IN (" + relatedHypers + ")"; - } - } - - if (!permittedAccounts.isEmpty() && !(templateFilter == TemplateFilter.featured || - templateFilter == TemplateFilter.community || templateFilter == TemplateFilter.executable - || templateFilter == TemplateFilter.shared || templateFilter == TemplateFilter.sharedexecutable) && !isAdmin(caller.getType()) ) { - whereClause += attr + "t.account_id IN (" + permittedAccountsStr + ")"; - } - - if (templateFilter == TemplateFilter.featured) { - whereClause += attr + "t.public = 1 AND t.featured = 1"; - if (!permittedAccounts.isEmpty()) { - whereClause += attr + "(dc.domain_id IN (" + relatedDomainIds + ") OR dc.domain_id is NULL)"; - } - } else if (templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) { - whereClause += " AND t.account_id IN (" + permittedAccountsStr + ")"; - } else if (templateFilter == TemplateFilter.sharedexecutable || templateFilter == TemplateFilter.shared ) { - whereClause += " AND " + - " (t.account_id IN (" + permittedAccountsStr + ") OR" + - " lp.account_id IN (" + permittedAccountsStr + "))"; - } else if (templateFilter == TemplateFilter.executable && !permittedAccounts.isEmpty()) { - whereClause += attr + "(t.public = 1 OR t.account_id IN (" + permittedAccountsStr + "))"; - } else if (templateFilter == TemplateFilter.community) { - whereClause += attr + "t.public = 1 AND t.featured = 0"; - if (!permittedAccounts.isEmpty()) { - whereClause += attr + "(dc.domain_id IN (" + relatedDomainIds + ") OR dc.domain_id is NULL)"; - } - } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && !isIso) { - return templateZonePairList; - } - - if (tags != null && !tags.isEmpty()) { - whereClause += " AND ("; - boolean first = true; - for (String key : tags.keySet()) { - if (!first) { - whereClause += " OR "; - } - whereClause += "(r.key=\"" + key + "\" and r.value=\"" + tags.get(key) + "\")"; - first = false; - } - whereClause += ")"; - } - - if (whereClause.equals("")) { - whereClause += " WHERE "; - } else if (!whereClause.equals(" WHERE ")) { - whereClause += " AND "; - } - - sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, bootable, hyperType, zoneId, - onlyReady, showDomr, zoneType) + groupByClause + getOrderByLimit(pageSize, startIndex); - - pstmt = txn.prepareStatement(sql); - rs = pstmt.executeQuery(); - - while (rs.next()) { - Pair templateZonePair = new Pair(rs.getLong(1), rs.getLong(2)); - templateZonePairList.add(templateZonePair); - } - //for now, defaulting pageSize to a large val if null; may need to revisit post 2.2RC2 - if(isIso && templateZonePairList.size() < (pageSize != null ? pageSize : 500) - && templateFilter != TemplateFilter.community - && !(templateFilter == TemplateFilter.self && !BaseCmd.isRootAdmin(caller.getType())) ){ //evaluates to true If root admin and filter=self - - List publicIsos = publicIsoSearch(bootable, false, tags); - List userIsos = userIsoSearch(false); - - //Listing the ISOs according to the page size.Restricting the total no. of ISOs on a page - //to be less than or equal to the pageSize parameter - - int i=0; - - if (startIndex > userIsos.size()) { - i=(int) (startIndex - userIsos.size()); - } - - for (; i < publicIsos.size(); i++) { - if(templateZonePairList.size() >= pageSize){ - break; - } else { - if (keyword != null && publicIsos.get(i).getName().contains(keyword)) { - templateZonePairList.add(new Pair(publicIsos.get(i).getId(), null)); - continue; - } else if (name != null && publicIsos.get(i).getName().contains(name)) { - templateZonePairList.add(new Pair(publicIsos.get(i).getId(), null)); - continue; - } else if (keyword == null && name == null){ - templateZonePairList.add(new Pair(publicIsos.get(i).getId(), null)); - } - } - } - } - } catch (Exception e) { - s_logger.warn("Error listing templates", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - txn.commit(); - } catch( SQLException sqle) { - s_logger.warn("Error in cleaning up", sqle); - } } - - return templateZonePairList; - } - */ - - /* - private String getExtrasWhere(TemplateFilter templateFilter, String name, String keyword, boolean isIso, Boolean bootable, HypervisorType hyperType, Long zoneId, boolean onlyReady, boolean showDomr, String zoneType) { - String sql = ""; - if (keyword != null) { - sql += " t.name LIKE \"%" + keyword + "%\" AND"; - } else if (name != null) { - sql += " t.name LIKE \"%" + name + "%\" AND"; - } - - if (isIso) { - sql += " t.format = 'ISO'"; - if (!hyperType.equals(HypervisorType.None)) { - sql += " AND goh.hypervisor_type = '" + hyperType.toString() + "'"; - } + VMTemplateZoneVO tmpltZoneVO = _templateZoneDao.findByZoneTemplate(zoneId, tmplt.getId()); + if (tmpltZoneVO == null) { + tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date()); + _templateZoneDao.persist(tmpltZoneVO); } else { - sql += " t.format <> 'ISO'"; - if (!hyperType.equals(HypervisorType.None)) { - sql += " AND t.hypervisor_type = '" + hyperType.toString() + "'"; - } + tmpltZoneVO.setRemoved(null); + tmpltZoneVO.setLastUpdated(new Date()); + _templateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); } + txn.commit(); - if (bootable != null) { - sql += " AND t.bootable = " + bootable; - } + return tmplt.getId(); + } - if (onlyReady){ - sql += " AND thr.download_state = '" +Status.DOWNLOADED.toString() + "'" + " AND thr.destroyed=0 "; - if (zoneId != null){ - sql += " AND h.data_center_id = " +zoneId; - } - }else if (zoneId != null){ - sql += " AND tzr.zone_id = " +zoneId+ " AND tzr.removed is null" ; - }else{ - sql += " AND tzr.removed is null "; - } + @Override + @DB + public List listAllInZone(long dataCenterId) { + SearchCriteria sc = TmpltsInZoneSearch.create(); + sc.setParameters("avoidtype", TemplateType.PERHOST.toString()); + sc.setJoinParameters("tmpltzone", "zoneId", dataCenterId); + return listBy(sc); + } - if (zoneType != null){ - sql += " AND dc.networktype = '" + zoneType + "'"; - } - - if (!showDomr){ - sql += " AND t.type != '" +Storage.TemplateType.SYSTEM.toString() + "'"; - } - - sql += " AND t.removed IS NULL"; - - return sql; - } - - private String getOrderByLimit(Long pageSize, Long startIndex) { - Boolean isAscending = Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); - isAscending = (isAscending == null ? true : isAscending); - - String sql; - if (isAscending) { - sql = " ORDER BY t.sort_key ASC"; - } else { - sql = " ORDER BY t.sort_key DESC"; - } - - if ((pageSize != null) && (startIndex != null)) { - sql += " LIMIT " + startIndex.toString() + "," + pageSize.toString(); - } - return sql; - } - */ - - @Override - @DB - public long addTemplateToZone(VMTemplateVO tmplt, long zoneId) { - Transaction txn = Transaction.currentTxn(); - txn.start(); - VMTemplateVO tmplt2 = findById(tmplt.getId()); - if (tmplt2 == null){ - if (persist(tmplt) == null) { - throw new CloudRuntimeException("Failed to persist the template " + tmplt); - } - if(tmplt.getDetails() != null) { - _templateDetailsDao.persist(tmplt.getId(), tmplt.getDetails()); - } - } - VMTemplateZoneVO tmpltZoneVO = _templateZoneDao.findByZoneTemplate(zoneId, tmplt.getId()); - if (tmpltZoneVO == null ) { - tmpltZoneVO = new VMTemplateZoneVO(zoneId, tmplt.getId(), new Date()); - _templateZoneDao.persist(tmpltZoneVO); - } else { - tmpltZoneVO.setRemoved(null); - tmpltZoneVO.setLastUpdated(new Date()); - _templateZoneDao.update(tmpltZoneVO.getId(), tmpltZoneVO); - } - txn.commit(); - - return tmplt.getId(); - } - - @Override - @DB - public List listAllInZone(long dataCenterId) { - SearchCriteria sc = TmpltsInZoneSearch.create(); - sc.setParameters("avoidtype", TemplateType.PERHOST.toString()); - sc.setJoinParameters("tmpltzone", "zoneId", dataCenterId); - return listBy(sc); - } - - - - @Override + @Override public List listAllActive() { SearchCriteria sc = ActiveTmpltSearch.create(); return listBy(sc); } @Override - public List listDefaultBuiltinTemplates() { - SearchCriteria sc = tmpltTypeSearch.create(); - sc.setParameters("templateType", Storage.TemplateType.BUILTIN); - return listBy(sc); - } + public List listDefaultBuiltinTemplates() { + SearchCriteria sc = tmpltTypeSearch.create(); + sc.setParameters("templateType", Storage.TemplateType.BUILTIN); + return listBy(sc); + } - @Override - public VMTemplateVO findSystemVMTemplate(long zoneId) { - SearchCriteria sc = tmpltTypeHyperSearch.create(); - sc.setParameters("templateType", Storage.TemplateType.SYSTEM); - sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); - sc.setJoinParameters("tmplHyper", "zoneId", zoneId); - - //order by descending order of id and select the first (this is going to be the latest) - List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1l)); - - if (tmplts.size() > 0) { - return tmplts.get(0); - } else { - return null; - } - } - - @Override - public VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType) { - SearchCriteria sc = tmpltTypeHyperSearch.create(); - sc.setParameters("templateType", Storage.TemplateType.SYSTEM); - sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); - sc.setJoinParameters("tmplHyper", "zoneId", zoneId); - - //order by descending order of id - List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null)); - - for (VMTemplateVO tmplt: tmplts) { - if (tmplt.getHypervisorType() == hType) { - return tmplt; - } - } - if (tmplts.size() > 0 && hType == HypervisorType.Any) { - return tmplts.get(0); - } - return null; - } - - @Override - public VMTemplateVO findRoutingTemplate(HypervisorType hType, String templateName) { - SearchCriteria sc = tmpltTypeHyperSearch2.create(); + @Override + public VMTemplateVO findSystemVMTemplate(long zoneId) { + SearchCriteria sc = tmpltTypeHyperSearch.create(); sc.setParameters("templateType", Storage.TemplateType.SYSTEM); - sc.setParameters("hypervisorType", hType); - if (templateName != null) { - sc.setParameters("templateName", templateName); - } + sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); + sc.setJoinParameters("tmplHyper", "zoneId", zoneId); - //order by descending order of id and select the first (this is going to be the latest) + // order by descending order of id and select the first (this is going + // to be the latest) List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1l)); if (tmplts.size() > 0) { @@ -929,11 +764,52 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem } else { return null; } - } + } + + @Override + public VMTemplateVO findSystemVMTemplate(long zoneId, HypervisorType hType) { + SearchCriteria sc = tmpltTypeHyperSearch.create(); + sc.setParameters("templateType", Storage.TemplateType.SYSTEM); + sc.setJoinParameters("tmplHyper", "type", Host.Type.Routing); + sc.setJoinParameters("tmplHyper", "zoneId", zoneId); + + // order by descending order of id + List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, null)); + + for (VMTemplateVO tmplt : tmplts) { + if (tmplt.getHypervisorType() == hType) { + return tmplt; + } + } + if (tmplts.size() > 0 && hType == HypervisorType.Any) { + return tmplts.get(0); + } + return null; + } + + @Override + public VMTemplateVO findRoutingTemplate(HypervisorType hType, String templateName) { + SearchCriteria sc = tmpltTypeHyperSearch2.create(); + sc.setParameters("templateType", Storage.TemplateType.SYSTEM); + sc.setParameters("hypervisorType", hType); + if (templateName != null) { + sc.setParameters("templateName", templateName); + } + + // order by descending order of id and select the first (this is going + // to be the latest) + List tmplts = listBy(sc, new Filter(VMTemplateVO.class, "id", false, null, 1l)); + + if (tmplts.size() > 0) { + return tmplts.get(0); + } else { + return null; + } + } @Override public Long countTemplatesForAccount(long accountId) { - SearchCriteria sc = CountTemplatesByAccount.create(); + SearchCriteria sc = CountTemplatesByAccount.create(); sc.setParameters("account", accountId); return customSearch(sc, null).get(0); } @@ -960,156 +836,108 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem return result; } - - @Override public List findTemplatesToSyncToS3() { return executeList(SELECT_S3_CANDIDATE_TEMPLATES, new Object[] {}); } /* - @Override - public Set> searchS3Templates(final String name, - final String keyword, final TemplateFilter templateFilter, - final boolean isIso, final List hypers, - final Boolean bootable, final DomainVO domain, final Long pageSize, - final Long startIndex, final Long zoneId, - final HypervisorType hyperType, final boolean onlyReady, - final boolean showDomr, final List permittedAccounts, - final Account caller, final Map tags) { - - final String permittedAccountsStr = join(",", permittedAccounts); - - final Transaction txn = Transaction.currentTxn(); - txn.start(); - - Set> templateZonePairList = new HashSet>(); - PreparedStatement pstmt = null; - ResultSet rs = null; - try { - - final StringBuilder joinClause = new StringBuilder(); - final StringBuilder whereClause = new StringBuilder(" WHERE t.removed IS NULL"); - - if (isIso) { - whereClause.append(" AND t.format = 'ISO'"); - if (!hyperType.equals(HypervisorType.None)) { - joinClause.append(" INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) "); - whereClause.append(" AND goh.hypervisor_type = '"); - whereClause.append(hyperType); - whereClause.append("'"); - } - } else { - whereClause.append(" AND t.format <> 'ISO'"); - if (hypers.isEmpty()) { - return templateZonePairList; - } else { - final StringBuilder relatedHypers = new StringBuilder(); - for (HypervisorType hyper : hypers) { - relatedHypers.append("'"); - relatedHypers.append(hyper.toString()); - relatedHypers.append("'"); - relatedHypers.append(","); - } - relatedHypers.setLength(relatedHypers.length() - 1); - whereClause.append(" AND t.hypervisor_type IN ("); - whereClause.append(relatedHypers); - whereClause.append(")"); - } - } - - joinClause.append(" INNER JOIN template_s3_ref tsr on (t.id = tsr.template_id)"); - - whereClause.append("AND t.name LIKE \"%"); - whereClause.append(keyword == null ? keyword : name); - whereClause.append("%\""); - - if (bootable != null) { - whereClause.append(" AND t.bootable = "); - whereClause.append(bootable); - } - - if (!showDomr) { - whereClause.append(" AND t.type != '"); - whereClause.append(Storage.TemplateType.SYSTEM); - whereClause.append("'"); - } - - if (templateFilter == TemplateFilter.featured) { - whereClause.append(" AND t.public = 1 AND t.featured = 1"); - } else if ((templateFilter == TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) - && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN - || caller.getType() == Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { - joinClause.append(" INNER JOIN account a on (t.account_id = a.id) INNER JOIN domain d on (a.domain_id = d.id)"); - whereClause.append(" AND d.path LIKE '"); - whereClause.append(domain.getPath()); - whereClause.append("%'"); - } else { - whereClause.append(" AND t.account_id IN ("); - whereClause.append(permittedAccountsStr); - whereClause.append(")"); - } - } else if (templateFilter == TemplateFilter.sharedexecutable - && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) { - joinClause.append(" LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE (t.account_id IN ("); - joinClause.append(permittedAccountsStr); - joinClause.append(") OR lp.account_id IN ("); - joinClause.append(permittedAccountsStr); - joinClause.append("))"); - } else { - joinClause.append(" INNER JOIN account a on (t.account_id = a.id) "); - } - } else if (templateFilter == TemplateFilter.executable - && !permittedAccounts.isEmpty()) { - whereClause.append(" AND (t.public = 1 OR t.account_id IN ("); - whereClause.append(permittedAccountsStr); - whereClause.append("))"); - } else if (templateFilter == TemplateFilter.community) { - whereClause.append(" AND t.public = 1 AND t.featured = 0"); - } else if (templateFilter == TemplateFilter.all - && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { - } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - return templateZonePairList; - } - - final StringBuilder sql = new StringBuilder(SELECT_TEMPLATE_S3_REF); - sql.append(joinClause); - sql.append(whereClause); - sql.append(getOrderByLimit(pageSize, startIndex)); - - pstmt = txn.prepareStatement(sql.toString()); - rs = pstmt.executeQuery(); - while (rs.next()) { - final Pair templateZonePair = new Pair( - rs.getLong(1), -1L); - templateZonePairList.add(templateZonePair); - } - txn.commit(); - } catch (Exception e) { - s_logger.warn("Error listing S3 templates", e); - if (txn != null) { - txn.rollback(); - } - } finally { - closeResources(pstmt, rs); - if (txn != null) { - txn.close(); - } - } - - return templateZonePairList; - } -*/ + * @Override public Set> searchS3Templates(final String + * name, final String keyword, final TemplateFilter templateFilter, final + * boolean isIso, final List hypers, final Boolean bootable, + * final DomainVO domain, final Long pageSize, final Long startIndex, final + * Long zoneId, final HypervisorType hyperType, final boolean onlyReady, + * final boolean showDomr, final List permittedAccounts, final + * Account caller, final Map tags) { + * + * final String permittedAccountsStr = join(",", permittedAccounts); + * + * final Transaction txn = Transaction.currentTxn(); txn.start(); + * + * Set> templateZonePairList = new HashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; try { + * + * final StringBuilder joinClause = new StringBuilder(); final StringBuilder + * whereClause = new StringBuilder(" WHERE t.removed IS NULL"); + * + * if (isIso) { whereClause.append(" AND t.format = 'ISO'"); if + * (!hyperType.equals(HypervisorType.None)) { joinClause.append( + * " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) " + * ); whereClause.append(" AND goh.hypervisor_type = '"); + * whereClause.append(hyperType); whereClause.append("'"); } } else { + * whereClause.append(" AND t.format <> 'ISO'"); if (hypers.isEmpty()) { + * return templateZonePairList; } else { final StringBuilder relatedHypers = + * new StringBuilder(); for (HypervisorType hyper : hypers) { + * relatedHypers.append("'"); relatedHypers.append(hyper.toString()); + * relatedHypers.append("'"); relatedHypers.append(","); } + * relatedHypers.setLength(relatedHypers.length() - 1); + * whereClause.append(" AND t.hypervisor_type IN ("); + * whereClause.append(relatedHypers); whereClause.append(")"); } } + * + * joinClause.append( + * " INNER JOIN template_s3_ref tsr on (t.id = tsr.template_id)"); + * + * whereClause.append("AND t.name LIKE \"%"); whereClause.append(keyword == + * null ? keyword : name); whereClause.append("%\""); + * + * if (bootable != null) { whereClause.append(" AND t.bootable = "); + * whereClause.append(bootable); } + * + * if (!showDomr) { whereClause.append(" AND t.type != '"); + * whereClause.append(Storage.TemplateType.SYSTEM); whereClause.append("'"); + * } + * + * if (templateFilter == TemplateFilter.featured) { + * whereClause.append(" AND t.public = 1 AND t.featured = 1"); } else if + * ((templateFilter == TemplateFilter.self || templateFilter == + * TemplateFilter.selfexecutable) && caller.getType() != + * Account.ACCOUNT_TYPE_ADMIN) { if (caller.getType() == + * Account.ACCOUNT_TYPE_DOMAIN_ADMIN || caller.getType() == + * Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN) { joinClause.append( + * " INNER JOIN account a on (t.account_id = a.id) INNER JOIN domain d on (a.domain_id = d.id)" + * ); whereClause.append(" AND d.path LIKE '"); + * whereClause.append(domain.getPath()); whereClause.append("%'"); } else { + * whereClause.append(" AND t.account_id IN ("); + * whereClause.append(permittedAccountsStr); whereClause.append(")"); } } + * else if (templateFilter == TemplateFilter.sharedexecutable && + * caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { if (caller.getType() == + * Account.ACCOUNT_TYPE_NORMAL) { joinClause.append( + * " LEFT JOIN launch_permission lp ON t.id = lp.template_id WHERE (t.account_id IN (" + * ); joinClause.append(permittedAccountsStr); + * joinClause.append(") OR lp.account_id IN ("); + * joinClause.append(permittedAccountsStr); joinClause.append("))"); } else + * { joinClause.append(" INNER JOIN account a on (t.account_id = a.id) "); } + * } else if (templateFilter == TemplateFilter.executable && + * !permittedAccounts.isEmpty()) { + * whereClause.append(" AND (t.public = 1 OR t.account_id IN ("); + * whereClause.append(permittedAccountsStr); whereClause.append("))"); } + * else if (templateFilter == TemplateFilter.community) { + * whereClause.append(" AND t.public = 1 AND t.featured = 0"); } else if + * (templateFilter == TemplateFilter.all && caller.getType() == + * Account.ACCOUNT_TYPE_ADMIN) { } else if (caller.getType() != + * Account.ACCOUNT_TYPE_ADMIN) { return templateZonePairList; } + * + * final StringBuilder sql = new StringBuilder(SELECT_TEMPLATE_S3_REF); + * sql.append(joinClause); sql.append(whereClause); + * sql.append(getOrderByLimit(pageSize, startIndex)); + * + * pstmt = txn.prepareStatement(sql.toString()); rs = pstmt.executeQuery(); + * while (rs.next()) { final Pair templateZonePair = new + * Pair( rs.getLong(1), -1L); + * templateZonePairList.add(templateZonePair); } txn.commit(); } catch + * (Exception e) { s_logger.warn("Error listing S3 templates", e); if (txn + * != null) { txn.rollback(); } } finally { closeResources(pstmt, rs); if + * (txn != null) { txn.close(); } } + * + * return templateZonePairList; } + */ @Override - public boolean updateState(TemplateState currentState, TemplateEvent event, - TemplateState nextState, VMTemplateVO vo, Object data) { + public boolean updateState(TemplateState currentState, TemplateEvent event, TemplateState nextState, + VMTemplateVO vo, Object data) { Long oldUpdated = vo.getUpdatedCount(); Date oldUpdatedTime = vo.getUpdated(); - SearchCriteria sc = updateStateSearch.create(); sc.setParameters("id", vo.getId()); sc.setParameters("state", currentState); @@ -1126,14 +954,18 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem VMTemplateVO dbVol = findByIdIncludingRemoved(vo.getId()); if (dbVol != null) { StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") + str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()) + .append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") .append(dbVol.getUpdated()); - str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()) + str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState) + .append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()) .append("; updatedTime=").append(vo.getUpdated()); - str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) + str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState) + .append("; event=").append(event).append("; updatecount=").append(oldUpdated) .append("; updatedTime=").append(oldUpdatedTime); } else { - s_logger.debug("Unable to update objectIndatastore: id=" + vo.getId() + ", as there is no such object exists in the database anymore"); + s_logger.debug("Unable to update objectIndatastore: id=" + vo.getId() + + ", as there is no such object exists in the database anymore"); } } return rows > 0; diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java index 5edea8e5586..552f8f00a86 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDao.java @@ -21,12 +21,12 @@ import java.util.Map; import com.cloud.storage.VMTemplateDetailVO; import com.cloud.utils.db.GenericDao; -public interface VMTemplateDetailsDao extends GenericDao { +public interface VMTemplateDetailsDao extends GenericDao { Map findDetails(long templateId); - + void persist(long templateId, Map details); - + VMTemplateDetailVO findDetail(long templateId, String name); - - void deleteDetails(long vmId); + + void deleteDetails(long vmId); } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java index 04b553c2f8b..33b96c45bcc 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java @@ -31,69 +31,69 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @Component -@Local(value=VMTemplateDetailsDao.class) +@Local(value = VMTemplateDetailsDao.class) public class VMTemplateDetailsDaoImpl extends GenericDaoBase implements VMTemplateDetailsDao { protected final SearchBuilder TemplateSearch; protected final SearchBuilder DetailSearch; - - public VMTemplateDetailsDaoImpl() { - TemplateSearch = createSearchBuilder(); - TemplateSearch.and("templateId", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateSearch.done(); - - DetailSearch = createSearchBuilder(); + + public VMTemplateDetailsDaoImpl() { + TemplateSearch = createSearchBuilder(); + TemplateSearch.and("templateId", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateSearch.done(); + + DetailSearch = createSearchBuilder(); DetailSearch.and("templateId", DetailSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ); DetailSearch.done(); - } - - @Override - public void deleteDetails(long templateId) { + } + + @Override + public void deleteDetails(long templateId) { SearchCriteria sc = TemplateSearch.create(); sc.setParameters("templateId", templateId); - + List results = search(sc, null); for (VMTemplateDetailVO result : results) { - remove(result.getId()); - } - } + remove(result.getId()); + } + } - @Override - public VMTemplateDetailVO findDetail(long templateId, String name) { + @Override + public VMTemplateDetailVO findDetail(long templateId, String name) { SearchCriteria sc = DetailSearch.create(); sc.setParameters("templateId", templateId); sc.setParameters("name", name); - - return findOneBy(sc); - } - @Override - public Map findDetails(long templateId) { + return findOneBy(sc); + } + + @Override + public Map findDetails(long templateId) { SearchCriteria sc = TemplateSearch.create(); sc.setParameters("templateId", templateId); - + List results = search(sc, null); Map details = new HashMap(results.size()); for (VMTemplateDetailVO result : results) { details.put(result.getName(), result.getValue()); } - - return details; - } - @Override - public void persist(long templateId, Map details) { + return details; + } + + @Override + public void persist(long templateId, Map details) { Transaction txn = Transaction.currentTxn(); txn.start(); SearchCriteria sc = TemplateSearch.create(); sc.setParameters("templateId", templateId); expunge(sc); - + for (Map.Entry detail : details.entrySet()) { VMTemplateDetailVO vo = new VMTemplateDetailVO(templateId, detail.getKey(), detail.getValue()); persist(vo); } - txn.commit(); - } + txn.commit(); + } } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDao.java index 23241cd17da..72072fa9325 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDao.java @@ -26,28 +26,31 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface VMTemplateHostDao extends GenericDao, StateDao { +public interface VMTemplateHostDao extends GenericDao, + StateDao { List listByHostId(long id); List listByTemplateId(long templateId); - + List listByOnlyTemplateId(long templateId); VMTemplateHostVO findByHostTemplate(long hostId, long templateId); - + VMTemplateHostVO findByTemplateId(long templateId); VMTemplateHostVO findByHostTemplate(long hostId, long templateId, boolean lock); List listByHostTemplate(long hostId, long templateId); - void update(VMTemplateHostVO instance); + void update(VMTemplateHostVO instance); List listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState); - List listByTemplateStatus(long templateId, long datacenterId, VMTemplateHostVO.Status downloadState); + List listByTemplateStatus(long templateId, long datacenterId, + VMTemplateHostVO.Status downloadState); - List listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateHostVO.Status downloadState); + List listByTemplateStatus(long templateId, long datacenterId, long podId, + VMTemplateHostVO.Status downloadState); List listByTemplateStates(long templateId, VMTemplateHostVO.Status... states); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java index 7f35eabfaa7..85d8348e36e 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateHostDaoImpl.java @@ -50,67 +50,61 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; @Component -@Local(value={VMTemplateHostDao.class}) +@Local(value = { VMTemplateHostDao.class }) public class VMTemplateHostDaoImpl extends GenericDaoBase implements VMTemplateHostDao { - public static final Logger s_logger = Logger.getLogger(VMTemplateHostDaoImpl.class.getName()); + public static final Logger s_logger = Logger.getLogger(VMTemplateHostDaoImpl.class.getName()); @Inject - HostDao _hostDao; - protected final SearchBuilder HostSearch; - protected final SearchBuilder TemplateSearch; - protected final SearchBuilder HostTemplateSearch; - protected final SearchBuilder HostTemplateStateSearch; - protected final SearchBuilder HostDestroyedSearch; - protected final SearchBuilder TemplateStatusSearch; - protected final SearchBuilder TemplateStatesSearch; - protected final SearchBuilder updateStateSearch; - protected SearchBuilder ZONE_TEMPLATE_SEARCH; - protected SearchBuilder LOCAL_SECONDARY_STORAGE_SEARCH; + HostDao _hostDao; + protected final SearchBuilder HostSearch; + protected final SearchBuilder TemplateSearch; + protected final SearchBuilder HostTemplateSearch; + protected final SearchBuilder HostTemplateStateSearch; + protected final SearchBuilder HostDestroyedSearch; + protected final SearchBuilder TemplateStatusSearch; + protected final SearchBuilder TemplateStatesSearch; + protected final SearchBuilder updateStateSearch; + protected SearchBuilder ZONE_TEMPLATE_SEARCH; + protected SearchBuilder LOCAL_SECONDARY_STORAGE_SEARCH; - - protected static final String UPDATE_TEMPLATE_HOST_REF = - "UPDATE template_host_ref SET download_state = ?, download_pct= ?, last_updated = ? " - + ", error_str = ?, local_path = ?, job_id = ? " - + "WHERE host_id = ? and type_id = ?"; - - protected static final String DOWNLOADS_STATE_DC= - "SELECT t.id, t.host_id, t.template_id, t.created, t.last_updated, t.job_id, " - + "t.download_pct, t.size, t.physical_size, t.download_state, t.error_str, t.local_path, " - + "t.install_path, t.url, t.destroyed, t.is_copy FROM template_host_ref t, host h " - + "where t.host_id = h.id and h.data_center_id=? " - + " and t.template_id=? and t.download_state = ?" ; - - protected static final String DOWNLOADS_STATE_DC_POD= - "SELECT * FROM template_host_ref t, host h where t.host_id = h.id and h.data_center_id=? and h.pod_id=? " - + " and t.template_id=? and t.download_state=?" ; - - protected static final String DOWNLOADS_STATE= - "SELECT * FROM template_host_ref t " - + " where t.template_id=? and t.download_state=?"; - - public VMTemplateHostDaoImpl () { - HostSearch = createSearchBuilder(); - HostSearch.and("host_id", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); - HostSearch.done(); - - TemplateSearch = createSearchBuilder(); - TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateSearch.and("destroyed", TemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - TemplateSearch.done(); - - HostTemplateSearch = createSearchBuilder(); - HostTemplateSearch.and("host_id", HostTemplateSearch.entity().getHostId(), SearchCriteria.Op.EQ); - HostTemplateSearch.and("template_id", HostTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + protected static final String UPDATE_TEMPLATE_HOST_REF = "UPDATE template_host_ref SET download_state = ?, download_pct= ?, last_updated = ? " + + ", error_str = ?, local_path = ?, job_id = ? " + "WHERE host_id = ? and type_id = ?"; + + protected static final String DOWNLOADS_STATE_DC = "SELECT t.id, t.host_id, t.template_id, t.created, t.last_updated, t.job_id, " + + "t.download_pct, t.size, t.physical_size, t.download_state, t.error_str, t.local_path, " + + "t.install_path, t.url, t.destroyed, t.is_copy FROM template_host_ref t, host h " + + "where t.host_id = h.id and h.data_center_id=? " + " and t.template_id=? and t.download_state = ?"; + + protected static final String DOWNLOADS_STATE_DC_POD = "SELECT * FROM template_host_ref t, host h where t.host_id = h.id and h.data_center_id=? and h.pod_id=? " + + " and t.template_id=? and t.download_state=?"; + + protected static final String DOWNLOADS_STATE = "SELECT * FROM template_host_ref t " + + " where t.template_id=? and t.download_state=?"; + + public VMTemplateHostDaoImpl() { + HostSearch = createSearchBuilder(); + HostSearch.and("host_id", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostSearch.done(); + + TemplateSearch = createSearchBuilder(); + TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateSearch.and("destroyed", TemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + TemplateSearch.done(); + + HostTemplateSearch = createSearchBuilder(); + HostTemplateSearch.and("host_id", HostTemplateSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostTemplateSearch.and("template_id", HostTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); HostTemplateSearch.and("destroyed", HostTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); HostTemplateSearch.done(); - - HostDestroyedSearch = createSearchBuilder(); - HostDestroyedSearch.and("host_id", HostDestroyedSearch.entity().getHostId(), SearchCriteria.Op.EQ); - HostDestroyedSearch.and("destroyed", HostDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - HostDestroyedSearch.done(); - - TemplateStatusSearch = createSearchBuilder(); - TemplateStatusSearch.and("template_id", TemplateStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateStatusSearch.and("download_state", TemplateStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); + + HostDestroyedSearch = createSearchBuilder(); + HostDestroyedSearch.and("host_id", HostDestroyedSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostDestroyedSearch.and("destroyed", HostDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); + HostDestroyedSearch.done(); + + TemplateStatusSearch = createSearchBuilder(); + TemplateStatusSearch.and("template_id", TemplateStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateStatusSearch.and("download_state", TemplateStatusSearch.entity().getDownloadState(), + SearchCriteria.Op.EQ); TemplateStatusSearch.and("destroyed", TemplateStatusSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); TemplateStatusSearch.done(); @@ -121,12 +115,14 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase params) throws ConfigurationException { - boolean result = super.configure(name, params); - ZONE_TEMPLATE_SEARCH = createSearchBuilder(); - ZONE_TEMPLATE_SEARCH.and("template_id", ZONE_TEMPLATE_SEARCH.entity().getTemplateId(), SearchCriteria.Op.EQ); - ZONE_TEMPLATE_SEARCH.and("state", ZONE_TEMPLATE_SEARCH.entity().getDownloadState(), SearchCriteria.Op.EQ); - SearchBuilder hostSearch = _hostDao.createSearchBuilder(); - hostSearch.and("zone_id", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - ZONE_TEMPLATE_SEARCH.join("tmplHost", hostSearch, hostSearch.entity().getId(), ZONE_TEMPLATE_SEARCH.entity().getHostId(), JoinBuilder.JoinType.INNER); - ZONE_TEMPLATE_SEARCH.done(); - - LOCAL_SECONDARY_STORAGE_SEARCH = createSearchBuilder(); - LOCAL_SECONDARY_STORAGE_SEARCH.and("template_id", LOCAL_SECONDARY_STORAGE_SEARCH.entity().getTemplateId(), SearchCriteria.Op.EQ); - LOCAL_SECONDARY_STORAGE_SEARCH.and("state", LOCAL_SECONDARY_STORAGE_SEARCH.entity().getDownloadState(), SearchCriteria.Op.EQ); - SearchBuilder localSecondaryHost = _hostDao.createSearchBuilder(); - localSecondaryHost.and("private_ip_address", localSecondaryHost.entity().getPrivateIpAddress(), SearchCriteria.Op.EQ); - localSecondaryHost.and("state", localSecondaryHost.entity().getStatus(), SearchCriteria.Op.EQ); - localSecondaryHost.and("data_center_id", localSecondaryHost.entity().getDataCenterId(), SearchCriteria.Op.EQ); - localSecondaryHost.and("type", localSecondaryHost.entity().getType(), SearchCriteria.Op.EQ); - LOCAL_SECONDARY_STORAGE_SEARCH.join("host", localSecondaryHost, localSecondaryHost.entity().getId(), LOCAL_SECONDARY_STORAGE_SEARCH.entity().getHostId(), JoinBuilder.JoinType.INNER); - LOCAL_SECONDARY_STORAGE_SEARCH.done(); - - return result; - } - @Override - public void update(VMTemplateHostVO instance) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - try { - Date now = new Date(); - String sql = UPDATE_TEMPLATE_HOST_REF; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setString(1, instance.getDownloadState().toString()); - pstmt.setInt(2, instance.getDownloadPercent()); - pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), now)); - pstmt.setString(4, instance.getErrorString()); - pstmt.setString(5, instance.getLocalDownloadPath()); - pstmt.setString(6, instance.getJobId()); - pstmt.setLong(7, instance.getHostId()); - pstmt.setLong(8, instance.getTemplateId()); - pstmt.executeUpdate(); - } catch (Exception e) { - s_logger.warn("Exception: ", e); - } - } - - @Override - public List listByHostId(long id) { - SearchCriteria sc = HostSearch.create(); - sc.setParameters("host_id", id); - return listIncludingRemovedBy(sc); - } - - @Override - public List listByTemplateId(long templateId) { - SearchCriteria sc = TemplateSearch.create(); - sc.setParameters("template_id", templateId); - sc.setParameters("destroyed", false); - return listIncludingRemovedBy(sc); - } - - - @Override - public List listByOnlyTemplateId(long templateId) { - SearchCriteria sc = TemplateSearch.create(); - sc.setParameters("template_id", templateId); - sc.setParameters("destroyed", false); - return listIncludingRemovedBy(sc); - } - - @Override - public VMTemplateHostVO findByHostTemplate(long hostId, long templateId) { - SearchCriteria sc = HostTemplateSearch.create(); - sc.setParameters("host_id", hostId); - sc.setParameters("template_id", templateId); - sc.setParameters("destroyed", false); - return findOneIncludingRemovedBy(sc); - } - - @Override - public VMTemplateHostVO findByTemplateId(long templateId) { - SearchCriteria sc = HostTemplateSearch.create(); - sc.setParameters("template_id", templateId); - sc.setParameters("destroyed", false); - return findOneIncludingRemovedBy(sc); - } - - @Override - public List listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState) { - SearchCriteria sc = TemplateStatusSearch.create(); - sc.setParameters("template_id", templateId); - sc.setParameters("download_state", downloadState.toString()); - sc.setParameters("destroyed", false); - return listIncludingRemovedBy(sc); - } - - @Override - public List listByTemplateStatus(long templateId, long datacenterId, VMTemplateHostVO.Status downloadState) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - try { - String sql = DOWNLOADS_STATE_DC; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, datacenterId); - pstmt.setLong(2, templateId); - pstmt.setString(3, downloadState.toString()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - result.add(toEntityBean(rs, false)); - } - } catch (Exception e) { - s_logger.warn("Exception: ", e); - } - return result; - } @Override - public List listByTemplateHostStatus(long templateId, long hostId, VMTemplateHostVO.Status... states) { + public boolean configure(String name, Map params) throws ConfigurationException { + boolean result = super.configure(name, params); + ZONE_TEMPLATE_SEARCH = createSearchBuilder(); + ZONE_TEMPLATE_SEARCH.and("template_id", ZONE_TEMPLATE_SEARCH.entity().getTemplateId(), SearchCriteria.Op.EQ); + ZONE_TEMPLATE_SEARCH.and("state", ZONE_TEMPLATE_SEARCH.entity().getDownloadState(), SearchCriteria.Op.EQ); + SearchBuilder hostSearch = _hostDao.createSearchBuilder(); + hostSearch.and("zone_id", hostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + ZONE_TEMPLATE_SEARCH.join("tmplHost", hostSearch, hostSearch.entity().getId(), ZONE_TEMPLATE_SEARCH.entity() + .getHostId(), JoinBuilder.JoinType.INNER); + ZONE_TEMPLATE_SEARCH.done(); + + LOCAL_SECONDARY_STORAGE_SEARCH = createSearchBuilder(); + LOCAL_SECONDARY_STORAGE_SEARCH.and("template_id", LOCAL_SECONDARY_STORAGE_SEARCH.entity().getTemplateId(), + SearchCriteria.Op.EQ); + LOCAL_SECONDARY_STORAGE_SEARCH.and("state", LOCAL_SECONDARY_STORAGE_SEARCH.entity().getDownloadState(), + SearchCriteria.Op.EQ); + SearchBuilder localSecondaryHost = _hostDao.createSearchBuilder(); + localSecondaryHost.and("private_ip_address", localSecondaryHost.entity().getPrivateIpAddress(), + SearchCriteria.Op.EQ); + localSecondaryHost.and("state", localSecondaryHost.entity().getStatus(), SearchCriteria.Op.EQ); + localSecondaryHost.and("data_center_id", localSecondaryHost.entity().getDataCenterId(), SearchCriteria.Op.EQ); + localSecondaryHost.and("type", localSecondaryHost.entity().getType(), SearchCriteria.Op.EQ); + LOCAL_SECONDARY_STORAGE_SEARCH.join("host", localSecondaryHost, localSecondaryHost.entity().getId(), + LOCAL_SECONDARY_STORAGE_SEARCH.entity().getHostId(), JoinBuilder.JoinType.INNER); + LOCAL_SECONDARY_STORAGE_SEARCH.done(); + + return result; + } + + @Override + public void update(VMTemplateHostVO instance) { + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + try { + Date now = new Date(); + String sql = UPDATE_TEMPLATE_HOST_REF; + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setString(1, instance.getDownloadState().toString()); + pstmt.setInt(2, instance.getDownloadPercent()); + pstmt.setString(3, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), now)); + pstmt.setString(4, instance.getErrorString()); + pstmt.setString(5, instance.getLocalDownloadPath()); + pstmt.setString(6, instance.getJobId()); + pstmt.setLong(7, instance.getHostId()); + pstmt.setLong(8, instance.getTemplateId()); + pstmt.executeUpdate(); + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } + } + + @Override + public List listByHostId(long id) { + SearchCriteria sc = HostSearch.create(); + sc.setParameters("host_id", id); + return listIncludingRemovedBy(sc); + } + + @Override + public List listByTemplateId(long templateId) { + SearchCriteria sc = TemplateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public List listByOnlyTemplateId(long templateId) { + SearchCriteria sc = TemplateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public VMTemplateHostVO findByHostTemplate(long hostId, long templateId) { + SearchCriteria sc = HostTemplateSearch.create(); + sc.setParameters("host_id", hostId); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + + @Override + public VMTemplateHostVO findByTemplateId(long templateId) { + SearchCriteria sc = HostTemplateSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("destroyed", false); + return findOneIncludingRemovedBy(sc); + } + + @Override + public List listByTemplateStatus(long templateId, VMTemplateHostVO.Status downloadState) { + SearchCriteria sc = TemplateStatusSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("download_state", downloadState.toString()); + sc.setParameters("destroyed", false); + return listIncludingRemovedBy(sc); + } + + @Override + public List listByTemplateStatus(long templateId, long datacenterId, + VMTemplateHostVO.Status downloadState) { + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + List result = new ArrayList(); + try { + String sql = DOWNLOADS_STATE_DC; + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setLong(1, datacenterId); + pstmt.setLong(2, templateId); + pstmt.setString(3, downloadState.toString()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + result.add(toEntityBean(rs, false)); + } + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } + return result; + } + + @Override + public List listByTemplateHostStatus(long templateId, long hostId, + VMTemplateHostVO.Status... states) { SearchCriteria sc = HostTemplateStateSearch.create(); sc.setParameters("template_id", templateId); sc.setParameters("host_id", hostId); - sc.setParameters("states", (Object[])states); + sc.setParameters("states", (Object[]) states); return search(sc, null); } - - @Override - public List listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateHostVO.Status downloadState) { + + @Override + public List listByTemplateStatus(long templateId, long datacenterId, long podId, + VMTemplateHostVO.Status downloadState) { Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - ResultSet rs = null; - try { - String sql = DOWNLOADS_STATE_DC_POD; - pstmt = txn.prepareStatement(sql); - - pstmt.setLong(1, datacenterId); - pstmt.setLong(2, podId); - pstmt.setLong(3, templateId); - pstmt.setString(4, downloadState.toString()); - rs = pstmt.executeQuery(); - while (rs.next()) { - // result.add(toEntityBean(rs, false)); TODO: this is buggy in GenericDaoBase for hand constructed queries - long id = rs.getLong(1); //ID column - result.add(findById(id)); + PreparedStatement pstmt = null; + List result = new ArrayList(); + ResultSet rs = null; + try { + String sql = DOWNLOADS_STATE_DC_POD; + pstmt = txn.prepareStatement(sql); + + pstmt.setLong(1, datacenterId); + pstmt.setLong(2, podId); + pstmt.setLong(3, templateId); + pstmt.setString(4, downloadState.toString()); + rs = pstmt.executeQuery(); + while (rs.next()) { + // result.add(toEntityBean(rs, false)); TODO: this is buggy in + // GenericDaoBase for hand constructed queries + long id = rs.getLong(1); // ID column + result.add(findById(id)); } - } catch (Exception e) { - s_logger.warn("Exception: ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } - } - return result; + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + return result; - } + } - @Override - public boolean templateAvailable(long templateId, long hostId) { - VMTemplateHostVO tmpltHost = findByHostTemplate(hostId, templateId); - if (tmpltHost == null) - return false; - - return tmpltHost.getDownloadState()==Status.DOWNLOADED; - } + @Override + public boolean templateAvailable(long templateId, long hostId) { + VMTemplateHostVO tmpltHost = findByHostTemplate(hostId, templateId); + if (tmpltHost == null) + return false; - @Override - public List listByTemplateStates(long templateId, VMTemplateHostVO.Status... states) { - SearchCriteria sc = TemplateStatesSearch.create(); - sc.setParameters("states", (Object[])states); - sc.setParameters("template_id", templateId); + return tmpltHost.getDownloadState() == Status.DOWNLOADED; + } + + @Override + public List listByTemplateStates(long templateId, VMTemplateHostVO.Status... states) { + SearchCriteria sc = TemplateStatesSearch.create(); + sc.setParameters("states", (Object[]) states); + sc.setParameters("template_id", templateId); sc.setParameters("destroyed", false); return search(sc, null); - } + } @Override public List listByState(VMTemplateHostVO.Status state) { @@ -324,14 +329,14 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase listByHostTemplate(long hostId, long templateId) { - SearchCriteria sc = HostTemplateSearch.create(); - sc.setParameters("host_id", hostId); + @Override + public List listByHostTemplate(long hostId, long templateId) { + SearchCriteria sc = HostTemplateSearch.create(); + sc.setParameters("host_id", hostId); sc.setParameters("template_id", templateId); sc.setParameters("destroyed", false); return listIncludingRemovedBy(sc); - } + } @Override public List listByZoneTemplate(long dcId, long templateId, boolean readyOnly) { @@ -340,61 +345,61 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase listDestroyed(long hostId) { - SearchCriteria sc = HostDestroyedSearch.create(); - sc.setParameters("host_id", hostId); - sc.setParameters("destroyed", true); - return listIncludingRemovedBy(sc); - } - @Override - public VMTemplateHostVO findByHostTemplate(long hostId, long templateId, boolean lock) { - SearchCriteria sc = HostTemplateSearch.create(); - sc.setParameters("host_id", hostId); - sc.setParameters("template_id", templateId); + @Override + public List listDestroyed(long hostId) { + SearchCriteria sc = HostDestroyedSearch.create(); + sc.setParameters("host_id", hostId); + sc.setParameters("destroyed", true); + return listIncludingRemovedBy(sc); + } + + @Override + public VMTemplateHostVO findByHostTemplate(long hostId, long templateId, boolean lock) { + SearchCriteria sc = HostTemplateSearch.create(); + sc.setParameters("host_id", hostId); + sc.setParameters("template_id", templateId); sc.setParameters("destroyed", false); - if (!lock) - return findOneIncludingRemovedBy(sc); - else - return lockOneRandomRow(sc, true); - } - - //Based on computing node host id, and template id, find out the corresponding template_host_ref, assuming local secondary storage and computing node is in the same zone, and private ip - @Override - public VMTemplateHostVO findLocalSecondaryStorageByHostTemplate(long hostId, long templateId) { - HostVO computingHost = _hostDao.findById(hostId); - SearchCriteria sc = LOCAL_SECONDARY_STORAGE_SEARCH.create(); - sc.setJoinParameters("host", "private_ip_address", computingHost.getPrivateIpAddress()); - sc.setJoinParameters("host", "state", com.cloud.host.Status.Up); - sc.setJoinParameters("host", "data_center_id", computingHost.getDataCenterId()); - sc.setJoinParameters("host", "type", Host.Type.LocalSecondaryStorage); - sc.setParameters("template_id", templateId); - sc.setParameters("state", VMTemplateHostVO.Status.DOWNLOADED); + if (!lock) + return findOneIncludingRemovedBy(sc); + else + return lockOneRandomRow(sc, true); + } + + // Based on computing node host id, and template id, find out the + // corresponding template_host_ref, assuming local secondary storage and + // computing node is in the same zone, and private ip + @Override + public VMTemplateHostVO findLocalSecondaryStorageByHostTemplate(long hostId, long templateId) { + HostVO computingHost = _hostDao.findById(hostId); + SearchCriteria sc = LOCAL_SECONDARY_STORAGE_SEARCH.create(); + sc.setJoinParameters("host", "private_ip_address", computingHost.getPrivateIpAddress()); + sc.setJoinParameters("host", "state", com.cloud.host.Status.Up); + sc.setJoinParameters("host", "data_center_id", computingHost.getDataCenterId()); + sc.setJoinParameters("host", "type", Host.Type.LocalSecondaryStorage); + sc.setParameters("template_id", templateId); + sc.setParameters("state", VMTemplateHostVO.Status.DOWNLOADED); sc.setParameters("destroyed", false); - return findOneBy(sc); - } + return findOneBy(sc); + } @Override public void deleteByHost(Long hostId) { List tmpltHosts = listByHostId(hostId); - for (VMTemplateHostVO tmpltHost : tmpltHosts ) { + for (VMTemplateHostVO tmpltHost : tmpltHosts) { remove(tmpltHost.getId()); } } - + @Override - public boolean updateState(State currentState, Event event, - State nextState, DataObjectInStore vo, Object data) { - VMTemplateHostVO templateHost = (VMTemplateHostVO)vo; + public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) { + VMTemplateHostVO templateHost = (VMTemplateHostVO) vo; Long oldUpdated = templateHost.getUpdatedCount(); Date oldUpdatedTime = templateHost.getUpdated(); - - + SearchCriteria sc = updateStateSearch.create(); sc.setParameters("id", templateHost.getId()); sc.setParameters("state", currentState); @@ -411,14 +416,19 @@ public class VMTemplateHostDaoImpl extends GenericDaoBase 0; diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDao.java index 501c3ca5cc8..7e6360b8960 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDao.java @@ -25,25 +25,29 @@ import com.cloud.storage.VMTemplateStoragePoolVO; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface VMTemplatePoolDao extends GenericDao, StateDao { - public List listByPoolId(long id); - - public List listByTemplateId(long templateId); - - public VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId); +public interface VMTemplatePoolDao extends GenericDao, + StateDao { + public List listByPoolId(long id); - public List listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState); - - public List listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId); + public List listByTemplateId(long templateId); - public List listByTemplateStatus(long templateId, long datacenterId, VMTemplateStoragePoolVO.Status downloadState); - - public List listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState); + public VMTemplateStoragePoolVO findByPoolTemplate(long poolId, long templateId); - public List listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status ... states); + public List listByTemplateStatus(long templateId, + VMTemplateStoragePoolVO.Status downloadState); - - boolean templateAvailable(long templateId, long poolId); + public List listByTemplateStatus(long templateId, + VMTemplateStoragePoolVO.Status downloadState, long poolId); - public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId); + public List listByTemplateStatus(long templateId, long datacenterId, + VMTemplateStoragePoolVO.Status downloadState); + + public List listByTemplateStatus(long templateId, long datacenterId, long podId, + VMTemplateStoragePoolVO.Status downloadState); + + public List listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status... states); + + boolean templateAvailable(long templateId, long poolId); + + public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId); } diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java index 5f212ebbfea..ba8135b5f32 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplatePoolDaoImpl.java @@ -42,105 +42,104 @@ import com.cloud.utils.db.Transaction; import com.cloud.utils.db.UpdateBuilder; @Component -@Local(value={VMTemplatePoolDao.class}) +@Local(value = { VMTemplatePoolDao.class }) public class VMTemplatePoolDaoImpl extends GenericDaoBase implements VMTemplatePoolDao { - public static final Logger s_logger = Logger.getLogger(VMTemplatePoolDaoImpl.class.getName()); - - protected final SearchBuilder PoolSearch; - protected final SearchBuilder TemplateSearch; - protected final SearchBuilder PoolTemplateSearch; - protected final SearchBuilder TemplateStatusSearch; - protected final SearchBuilder TemplatePoolStatusSearch; - protected final SearchBuilder TemplateStatesSearch; - protected final SearchBuilder updateStateSearch; - - protected static final String UPDATE_TEMPLATE_HOST_REF = - "UPDATE template_spool_ref SET download_state = ?, download_pct= ?, last_updated = ? " - + ", error_str = ?, local_path = ?, job_id = ? " - + "WHERE pool_id = ? and template_id = ?"; - - protected static final String DOWNLOADS_STATE_DC= - "SELECT * FROM template_spool_ref t, storage_pool p where t.pool_id = p.id and p.data_center_id=? " - + " and t.template_id=? and t.download_state = ?" ; - - protected static final String DOWNLOADS_STATE_DC_POD= - "SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.data_center_id=? and h.pod_id=? " - + " and tp.template_id=? and tp.download_state=?" ; - - protected static final String HOST_TEMPLATE_SEARCH= - "SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.id=? " - + " and tp.template_id=? " ; - - - public VMTemplatePoolDaoImpl () { - PoolSearch = createSearchBuilder(); - PoolSearch.and("pool_id", PoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - PoolSearch.done(); - - TemplateSearch = createSearchBuilder(); - TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateSearch.done(); - - PoolTemplateSearch = createSearchBuilder(); - PoolTemplateSearch.and("pool_id", PoolTemplateSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - PoolTemplateSearch.and("template_id", PoolTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - PoolTemplateSearch.done(); - - TemplateStatusSearch = createSearchBuilder(); - TemplateStatusSearch.and("template_id", TemplateStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateStatusSearch.and("download_state", TemplateStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); - TemplateStatusSearch.done(); + public static final Logger s_logger = Logger.getLogger(VMTemplatePoolDaoImpl.class.getName()); - TemplatePoolStatusSearch = createSearchBuilder(); - TemplatePoolStatusSearch.and("pool_id", TemplatePoolStatusSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - TemplatePoolStatusSearch.and("template_id", TemplatePoolStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplatePoolStatusSearch.and("download_state", TemplatePoolStatusSearch.entity().getDownloadState(), SearchCriteria.Op.EQ); - TemplatePoolStatusSearch.done(); + protected final SearchBuilder PoolSearch; + protected final SearchBuilder TemplateSearch; + protected final SearchBuilder PoolTemplateSearch; + protected final SearchBuilder TemplateStatusSearch; + protected final SearchBuilder TemplatePoolStatusSearch; + protected final SearchBuilder TemplateStatesSearch; + protected final SearchBuilder updateStateSearch; + + protected static final String UPDATE_TEMPLATE_HOST_REF = "UPDATE template_spool_ref SET download_state = ?, download_pct= ?, last_updated = ? " + + ", error_str = ?, local_path = ?, job_id = ? " + "WHERE pool_id = ? and template_id = ?"; + + protected static final String DOWNLOADS_STATE_DC = "SELECT * FROM template_spool_ref t, storage_pool p where t.pool_id = p.id and p.data_center_id=? " + + " and t.template_id=? and t.download_state = ?"; + + protected static final String DOWNLOADS_STATE_DC_POD = "SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.data_center_id=? and h.pod_id=? " + + " and tp.template_id=? and tp.download_state=?"; + + protected static final String HOST_TEMPLATE_SEARCH = "SELECT * FROM template_spool_ref tp, storage_pool_host_ref ph, host h where tp.pool_id = ph.pool_id and ph.host_id = h.id and h.id=? " + + " and tp.template_id=? "; + + public VMTemplatePoolDaoImpl() { + PoolSearch = createSearchBuilder(); + PoolSearch.and("pool_id", PoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ); + PoolSearch.done(); + + TemplateSearch = createSearchBuilder(); + TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateSearch.done(); + + PoolTemplateSearch = createSearchBuilder(); + PoolTemplateSearch.and("pool_id", PoolTemplateSearch.entity().getPoolId(), SearchCriteria.Op.EQ); + PoolTemplateSearch.and("template_id", PoolTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + PoolTemplateSearch.done(); + + TemplateStatusSearch = createSearchBuilder(); + TemplateStatusSearch.and("template_id", TemplateStatusSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateStatusSearch.and("download_state", TemplateStatusSearch.entity().getDownloadState(), + SearchCriteria.Op.EQ); + TemplateStatusSearch.done(); + + TemplatePoolStatusSearch = createSearchBuilder(); + TemplatePoolStatusSearch.and("pool_id", TemplatePoolStatusSearch.entity().getPoolId(), SearchCriteria.Op.EQ); + TemplatePoolStatusSearch.and("template_id", TemplatePoolStatusSearch.entity().getTemplateId(), + SearchCriteria.Op.EQ); + TemplatePoolStatusSearch.and("download_state", TemplatePoolStatusSearch.entity().getDownloadState(), + SearchCriteria.Op.EQ); + TemplatePoolStatusSearch.done(); TemplateStatesSearch = createSearchBuilder(); - TemplateStatesSearch.and("template_id", TemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateStatesSearch.and("states", TemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.IN); - TemplateStatesSearch.done(); + TemplateStatesSearch.and("template_id", TemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateStatesSearch.and("states", TemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.IN); + TemplateStatesSearch.done(); - updateStateSearch = this.createSearchBuilder(); - updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); - updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); - updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); - updateStateSearch.done(); - } + updateStateSearch = this.createSearchBuilder(); + updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); + updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); + updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); + updateStateSearch.done(); + } - @Override - public List listByPoolId(long id) { - SearchCriteria sc = PoolSearch.create(); - sc.setParameters("pool_id", id); - return listIncludingRemovedBy(sc); - } + @Override + public List listByPoolId(long id) { + SearchCriteria sc = PoolSearch.create(); + sc.setParameters("pool_id", id); + return listIncludingRemovedBy(sc); + } - @Override - public List listByTemplateId(long templateId) { - SearchCriteria sc = TemplateSearch.create(); - sc.setParameters("template_id", templateId); - return listIncludingRemovedBy(sc); - } + @Override + public List listByTemplateId(long templateId) { + SearchCriteria sc = TemplateSearch.create(); + sc.setParameters("template_id", templateId); + return listIncludingRemovedBy(sc); + } - @Override - public VMTemplateStoragePoolVO findByPoolTemplate(long hostId, long templateId) { - SearchCriteria sc = PoolTemplateSearch.create(); - sc.setParameters("pool_id", hostId); - sc.setParameters("template_id", templateId); - return findOneIncludingRemovedBy(sc); - } + @Override + public VMTemplateStoragePoolVO findByPoolTemplate(long hostId, long templateId) { + SearchCriteria sc = PoolTemplateSearch.create(); + sc.setParameters("pool_id", hostId); + sc.setParameters("template_id", templateId); + return findOneIncludingRemovedBy(sc); + } - @Override - public List listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState) { - SearchCriteria sc = TemplateStatusSearch.create(); - sc.setParameters("template_id", templateId); - sc.setParameters("download_state", downloadState.toString()); - return listIncludingRemovedBy(sc); - } + @Override + public List listByTemplateStatus(long templateId, + VMTemplateStoragePoolVO.Status downloadState) { + SearchCriteria sc = TemplateStatusSearch.create(); + sc.setParameters("template_id", templateId); + sc.setParameters("download_state", downloadState.toString()); + return listIncludingRemovedBy(sc); + } - @Override - public List listByTemplateStatus(long templateId, VMTemplateStoragePoolVO.Status downloadState, long poolId) { + @Override + public List listByTemplateStatus(long templateId, + VMTemplateStoragePoolVO.Status downloadState, long poolId) { SearchCriteria sc = TemplatePoolStatusSearch.create(); sc.setParameters("pool_id", poolId); sc.setParameters("template_id", templateId); @@ -148,130 +147,133 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase listByTemplateStatus(long templateId, long datacenterId, VMTemplateStoragePoolVO.Status downloadState) { + @Override + public List listByTemplateStatus(long templateId, long datacenterId, + VMTemplateStoragePoolVO.Status downloadState) { Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - try { - String sql = DOWNLOADS_STATE_DC; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, datacenterId); - pstmt.setLong(2, templateId); - pstmt.setString(3, downloadState.toString()); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { + PreparedStatement pstmt = null; + List result = new ArrayList(); + try { + String sql = DOWNLOADS_STATE_DC; + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setLong(1, datacenterId); + pstmt.setLong(2, templateId); + pstmt.setString(3, downloadState.toString()); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { result.add(toEntityBean(rs, false)); } - } catch (Exception e) { - s_logger.warn("Exception: ", e); - } - return result; + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } + return result; - } - - @Override - public List listByTemplateStatus(long templateId, long datacenterId, long podId, VMTemplateStoragePoolVO.Status downloadState) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - ResultSet rs = null; - try { - String sql = DOWNLOADS_STATE_DC_POD; - pstmt = txn.prepareStatement(sql); - - pstmt.setLong(1, datacenterId); - pstmt.setLong(2, podId); - pstmt.setLong(3, templateId); - pstmt.setString(4, downloadState.toString()); - rs = pstmt.executeQuery(); - while (rs.next()) { - // result.add(toEntityBean(rs, false)); TODO: this is buggy in GenericDaoBase for hand constructed queries - long id = rs.getLong(1); //ID column - result.add(findById(id)); - } - } catch (Exception e) { - s_logger.warn("Exception: ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } - } - return result; - - } - - public List listByHostTemplate(long hostId, long templateId) { - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; - List result = new ArrayList(); - ResultSet rs = null; - try { - String sql = HOST_TEMPLATE_SEARCH; - pstmt = txn.prepareStatement(sql); - - pstmt.setLong(1, hostId); - pstmt.setLong(2, templateId); - rs = pstmt.executeQuery(); - while (rs.next()) { - // result.add(toEntityBean(rs, false)); TODO: this is buggy in GenericDaoBase for hand constructed queries - long id = rs.getLong(1); //ID column - result.add(findById(id)); - } - } catch (Exception e) { - s_logger.warn("Exception: ", e); - } finally { - try { - if (rs != null) { - rs.close(); - } - if (pstmt != null) { - pstmt.close(); - } - } catch (SQLException e) { - } - } - return result; - - } - - @Override - public boolean templateAvailable(long templateId, long hostId) { - VMTemplateStorageResourceAssoc tmpltPool = findByPoolTemplate(hostId, templateId); - if (tmpltPool == null) - return false; - - return tmpltPool.getDownloadState()==Status.DOWNLOADED; - } - - @Override - public List listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status... states) { - SearchCriteria sc = TemplateStatesSearch.create(); - sc.setParameters("states", (Object[])states); - sc.setParameters("template_id", templateId); - - return search(sc, null); - } - - @Override - public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId) { - List result = listByHostTemplate(hostId, templateId); - return (result.size() == 0)?null:result.get(1); - } + } @Override - public boolean updateState(State currentState, Event event, - State nextState, DataObjectInStore vo, Object data) { - VMTemplateStoragePoolVO templatePool = (VMTemplateStoragePoolVO)vo; + public List listByTemplateStatus(long templateId, long datacenterId, long podId, + VMTemplateStoragePoolVO.Status downloadState) { + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + List result = new ArrayList(); + ResultSet rs = null; + try { + String sql = DOWNLOADS_STATE_DC_POD; + pstmt = txn.prepareStatement(sql); + + pstmt.setLong(1, datacenterId); + pstmt.setLong(2, podId); + pstmt.setLong(3, templateId); + pstmt.setString(4, downloadState.toString()); + rs = pstmt.executeQuery(); + while (rs.next()) { + // result.add(toEntityBean(rs, false)); TODO: this is buggy in + // GenericDaoBase for hand constructed queries + long id = rs.getLong(1); // ID column + result.add(findById(id)); + } + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + return result; + + } + + public List listByHostTemplate(long hostId, long templateId) { + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; + List result = new ArrayList(); + ResultSet rs = null; + try { + String sql = HOST_TEMPLATE_SEARCH; + pstmt = txn.prepareStatement(sql); + + pstmt.setLong(1, hostId); + pstmt.setLong(2, templateId); + rs = pstmt.executeQuery(); + while (rs.next()) { + // result.add(toEntityBean(rs, false)); TODO: this is buggy in + // GenericDaoBase for hand constructed queries + long id = rs.getLong(1); // ID column + result.add(findById(id)); + } + } catch (Exception e) { + s_logger.warn("Exception: ", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + return result; + + } + + @Override + public boolean templateAvailable(long templateId, long hostId) { + VMTemplateStorageResourceAssoc tmpltPool = findByPoolTemplate(hostId, templateId); + if (tmpltPool == null) + return false; + + return tmpltPool.getDownloadState() == Status.DOWNLOADED; + } + + @Override + public List listByTemplateStates(long templateId, VMTemplateStoragePoolVO.Status... states) { + SearchCriteria sc = TemplateStatesSearch.create(); + sc.setParameters("states", (Object[]) states); + sc.setParameters("template_id", templateId); + + return search(sc, null); + } + + @Override + public VMTemplateStoragePoolVO findByHostTemplate(Long hostId, Long templateId) { + List result = listByHostTemplate(hostId, templateId); + return (result.size() == 0) ? null : result.get(1); + } + + @Override + public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) { + VMTemplateStoragePoolVO templatePool = (VMTemplateStoragePoolVO) vo; Long oldUpdated = templatePool.getUpdatedCount(); Date oldUpdatedTime = templatePool.getUpdated(); - + SearchCriteria sc = updateStateSearch.create(); sc.setParameters("id", templatePool.getId()); sc.setParameters("state", currentState); @@ -288,14 +290,19 @@ public class VMTemplatePoolDaoImpl extends GenericDaoBase 0; diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java index 7cfd3b5937c..d49645d944a 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateS3DaoImpl.java @@ -34,8 +34,7 @@ import java.util.List; @Component @Local(VMTemplateS3Dao.class) -public class VMTemplateS3DaoImpl extends GenericDaoBase - implements VMTemplateS3Dao { +public class VMTemplateS3DaoImpl extends GenericDaoBase implements VMTemplateS3Dao { private final SearchBuilder searchBuilder; @@ -44,19 +43,15 @@ public class VMTemplateS3DaoImpl extends GenericDaoBase super(); this.searchBuilder = createSearchBuilder(); - this.searchBuilder - .and(S3_ID_COLUMN_NAME, this.searchBuilder.entity().getS3Id(), - EQ) - .and(TEMPLATE_ID_COLUMN_NAME, - this.searchBuilder.entity().getTemplateId(), EQ).done(); + this.searchBuilder.and(S3_ID_COLUMN_NAME, this.searchBuilder.entity().getS3Id(), EQ) + .and(TEMPLATE_ID_COLUMN_NAME, this.searchBuilder.entity().getTemplateId(), EQ).done(); } @Override public List listByS3Id(final long s3id) { - final SearchCriteria criteria = this.searchBuilder - .create(); + final SearchCriteria criteria = this.searchBuilder.create(); criteria.setParameters(S3_ID_COLUMN_NAME, s3id); @@ -67,8 +62,7 @@ public class VMTemplateS3DaoImpl extends GenericDaoBase @Override public VMTemplateS3VO findOneByTemplateId(final long templateId) { - final SearchCriteria criteria = this.searchBuilder - .create(); + final SearchCriteria criteria = this.searchBuilder.create(); criteria.setParameters(TEMPLATE_ID_COLUMN_NAME, templateId); @@ -77,11 +71,9 @@ public class VMTemplateS3DaoImpl extends GenericDaoBase } @Override - public VMTemplateS3VO findOneByS3Template(final long s3Id, - final long templateId) { + public VMTemplateS3VO findOneByS3Template(final long s3Id, final long templateId) { - final SearchCriteria criteria = this.searchBuilder - .create(); + final SearchCriteria criteria = this.searchBuilder.create(); criteria.setParameters(S3_ID_COLUMN_NAME, s3Id); criteria.setParameters(TEMPLATE_ID_COLUMN_NAME, templateId); @@ -93,8 +85,7 @@ public class VMTemplateS3DaoImpl extends GenericDaoBase @Override public void expungeAllByTemplateId(long templateId) { - final SearchCriteria criteria = this.searchBuilder - .create(); + final SearchCriteria criteria = this.searchBuilder.create(); criteria.setParameters(TEMPLATE_ID_COLUMN_NAME, templateId); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java index 27e05c92e3d..67f7c3f64d7 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDao.java @@ -22,11 +22,11 @@ import com.cloud.storage.VMTemplateZoneVO; import com.cloud.utils.db.GenericDao; public interface VMTemplateZoneDao extends GenericDao { - public List listByZoneId(long id); + public List listByZoneId(long id); - public List listByTemplateId(long templateId); + public List listByTemplateId(long templateId); - public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId); + public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId); public List listByZoneTemplate(Long zoneId, long templateId); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java index 27b554cdb8a..c4a4dc7230a 100644 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateZoneDaoImpl.java @@ -20,7 +20,6 @@ import java.util.List; import javax.ejb.Local; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -31,63 +30,60 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @Component -@Local(value={VMTemplateZoneDao.class}) +@Local(value = { VMTemplateZoneDao.class }) public class VMTemplateZoneDaoImpl extends GenericDaoBase implements VMTemplateZoneDao { - public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName()); + public static final Logger s_logger = Logger.getLogger(VMTemplateZoneDaoImpl.class.getName()); - protected final SearchBuilder ZoneSearch; - protected final SearchBuilder TemplateSearch; - protected final SearchBuilder ZoneTemplateSearch; + protected final SearchBuilder ZoneSearch; + protected final SearchBuilder TemplateSearch; + protected final SearchBuilder ZoneTemplateSearch; + public VMTemplateZoneDaoImpl() { + ZoneSearch = createSearchBuilder(); + ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); + ZoneSearch.done(); - public VMTemplateZoneDaoImpl () { - ZoneSearch = createSearchBuilder(); - ZoneSearch.and("zone_id", ZoneSearch.entity().getZoneId(), SearchCriteria.Op.EQ); - ZoneSearch.done(); + TemplateSearch = createSearchBuilder(); + TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + TemplateSearch.done(); - TemplateSearch = createSearchBuilder(); - TemplateSearch.and("template_id", TemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - TemplateSearch.done(); + ZoneTemplateSearch = createSearchBuilder(); + ZoneTemplateSearch.and("zone_id", ZoneTemplateSearch.entity().getZoneId(), SearchCriteria.Op.EQ); + ZoneTemplateSearch.and("template_id", ZoneTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); + ZoneTemplateSearch.done(); + } - ZoneTemplateSearch = createSearchBuilder(); - ZoneTemplateSearch.and("zone_id", ZoneTemplateSearch.entity().getZoneId(), SearchCriteria.Op.EQ); - ZoneTemplateSearch.and("template_id", ZoneTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ); - ZoneTemplateSearch.done(); - } + @Override + public List listByZoneId(long id) { + SearchCriteria sc = ZoneSearch.create(); + sc.setParameters("zone_id", id); + return listIncludingRemovedBy(sc); + } + @Override + public List listByTemplateId(long templateId) { + SearchCriteria sc = TemplateSearch.create(); + sc.setParameters("template_id", templateId); + return listIncludingRemovedBy(sc); + } - @Override - public List listByZoneId(long id) { - SearchCriteria sc = ZoneSearch.create(); - sc.setParameters("zone_id", id); - return listIncludingRemovedBy(sc); - } + @Override + public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId) { + SearchCriteria sc = ZoneTemplateSearch.create(); + sc.setParameters("zone_id", zoneId); + sc.setParameters("template_id", templateId); + return findOneIncludingRemovedBy(sc); + } - @Override - public List listByTemplateId(long templateId) { - SearchCriteria sc = TemplateSearch.create(); - sc.setParameters("template_id", templateId); - return listIncludingRemovedBy(sc); - } - - @Override - public VMTemplateZoneVO findByZoneTemplate(long zoneId, long templateId) { - SearchCriteria sc = ZoneTemplateSearch.create(); - sc.setParameters("zone_id", zoneId); - sc.setParameters("template_id", templateId); - return findOneIncludingRemovedBy(sc); - } - - @Override + @Override public List listByZoneTemplate(Long zoneId, long templateId) { - SearchCriteria sc = ZoneTemplateSearch.create(); + SearchCriteria sc = ZoneTemplateSearch.create(); if (zoneId != null) { sc.setParameters("zone_id", zoneId); } - sc.setParameters("template_id", templateId); - return listBy(sc); - } - + sc.setParameters("template_id", templateId); + return listBy(sc); + } @Override public void deletePrimaryRecordsForTemplate(long templateId) { @@ -100,5 +96,4 @@ public class VMTemplateZoneDaoImpl extends GenericDaoBase, StateDao findUsableVolumesForInstance(long instanceId); - Long countAllocatedVolumesForAccount(long accountId); + Long countAllocatedVolumesForAccount(long accountId); HypervisorType getHypervisorType(long volumeId); @@ -76,15 +76,16 @@ public interface VolumeDao extends GenericDao, StateDao implements VolumeDao { private static final Logger s_logger = Logger.getLogger(VolumeDaoImpl.class); protected final SearchBuilder DetachedAccountIdSearch; @@ -63,23 +63,23 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol protected GenericSearchBuilder CountByAccount; protected GenericSearchBuilder primaryStorageSearch; protected GenericSearchBuilder secondaryStorageSearch; - @Inject ResourceTagDao _tagsDao; + @Inject + ResourceTagDao _tagsDao; protected static final String SELECT_VM_SQL = "SELECT DISTINCT instance_id from volumes v where v.host_id = ? and v.mirror_state = ?"; protected static final String SELECT_HYPERTYPE_FROM_VOLUME = "SELECT c.hypervisor_type from volumes v, storage_pool s, cluster c where v.pool_id = s.id and s.cluster_id = c.id and v.id = ?"; - private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? " + - " AND pool.pod_id = ? AND pool.cluster_id = ? " + - " GROUP BY pool.id ORDER BY 2 ASC "; - + private static final String ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT = "SELECT pool.id, SUM(IF(vol.state='Ready' AND vol.account_id = ?, 1, 0)) FROM `cloud`.`storage_pool` pool LEFT JOIN `cloud`.`volumes` vol ON pool.id = vol.pool_id WHERE pool.data_center_id = ? " + + " AND pool.pod_id = ? AND pool.cluster_id = ? " + " GROUP BY pool.id ORDER BY 2 ASC "; + @Override public List findDetachedByAccount(long accountId) { - SearchCriteria sc = DetachedAccountIdSearch.create(); - sc.setParameters("accountId", accountId); - sc.setParameters("destroyed", Volume.State.Destroy); - return listBy(sc); + SearchCriteria sc = DetachedAccountIdSearch.create(); + sc.setParameters("accountId", accountId); + sc.setParameters("destroyed", Volume.State.Destroy); + return listBy(sc); } - + @Override public List findByAccount(long accountId) { SearchCriteria sc = AllFieldsSearch.create(); @@ -87,172 +87,172 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol sc.setParameters("state", Volume.State.Ready); return listBy(sc); } - + @Override public List findByInstance(long id) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", id); - return listBy(sc); - } - - @Override - public List findByInstanceAndDeviceId(long instanceId, long deviceId){ - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - sc.setParameters("deviceId", deviceId); - return listBy(sc); + return listBy(sc); } - + + @Override + public List findByInstanceAndDeviceId(long instanceId, long deviceId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("instanceId", instanceId); + sc.setParameters("deviceId", deviceId); + return listBy(sc); + } + @Override public List findByPoolId(long poolId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("poolId", poolId); sc.setParameters("notDestroyed", Volume.State.Destroy); sc.setParameters("vType", Volume.Type.ROOT.toString()); - return listBy(sc); - } - - @Override + return listBy(sc); + } + + @Override public List findCreatedByInstance(long id) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", id); sc.setParameters("state", Volume.State.Ready); return listBy(sc); } - + @Override public List findUsableVolumesForInstance(long instanceId) { SearchCriteria sc = InstanceStatesSearch.create(); sc.setParameters("instance", instanceId); sc.setParameters("states", Volume.State.Creating, Volume.State.Ready, Volume.State.Allocated); - + return listBy(sc); } - - @Override - public List findByInstanceAndType(long id, Type vType) { + + @Override + public List findByInstanceAndType(long id, Type vType) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", id); sc.setParameters("vType", vType.toString()); - return listBy(sc); - } - - @Override - public List findByInstanceIdDestroyed(long vmId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", vmId); - sc.setParameters("destroyed", Volume.State.Destroy); - return listBy(sc); - } - - @Override - public List findReadyRootVolumesByInstance(long instanceId) { - SearchCriteria sc = AllFieldsSearch.create(); - sc.setParameters("instanceId", instanceId); - sc.setParameters("state", Volume.State.Ready); - sc.setParameters("vType", Volume.Type.ROOT); - return listBy(sc); - } - - @Override - public List findByAccountAndPod(long accountId, long podId) { - SearchCriteria sc = AllFieldsSearch.create(); + return listBy(sc); + } + + @Override + public List findByInstanceIdDestroyed(long vmId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("instanceId", vmId); + sc.setParameters("destroyed", Volume.State.Destroy); + return listBy(sc); + } + + @Override + public List findReadyRootVolumesByInstance(long instanceId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("instanceId", instanceId); + sc.setParameters("state", Volume.State.Ready); + sc.setParameters("vType", Volume.Type.ROOT); + return listBy(sc); + } + + @Override + public List findByAccountAndPod(long accountId, long podId) { + SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("accountId", accountId); sc.setParameters("pod", podId); sc.setParameters("state", Volume.State.Ready); - - return listIncludingRemovedBy(sc); - } - - @Override - public List findByTemplateAndZone(long templateId, long zoneId) { - SearchCriteria sc = TemplateZoneSearch.create(); - sc.setParameters("template", templateId); - sc.setParameters("zone", zoneId); - - return listIncludingRemovedBy(sc); - } - @Override - public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) { - SearchCriteria sc = ActiveTemplateSearch.create(); - sc.setParameters("template", templateId); - sc.setParameters("pool", poolId); - - List results = customSearchIncludingRemoved(sc, null); - assert results.size() > 0 : "How can this return a size of " + results.size(); - - return results.get(0) > 0; - } - + return listIncludingRemovedBy(sc); + } + + @Override + public List findByTemplateAndZone(long templateId, long zoneId) { + SearchCriteria sc = TemplateZoneSearch.create(); + sc.setParameters("template", templateId); + sc.setParameters("zone", zoneId); + + return listIncludingRemovedBy(sc); + } + + @Override + public boolean isAnyVolumeActivelyUsingTemplateOnPool(long templateId, long poolId) { + SearchCriteria sc = ActiveTemplateSearch.create(); + sc.setParameters("template", templateId); + sc.setParameters("pool", poolId); + + List results = customSearchIncludingRemoved(sc, null); + assert results.size() > 0 : "How can this return a size of " + results.size(); + + return results.get(0) > 0; + } + @Override public void deleteVolumesByInstance(long instanceId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("instanceId", instanceId); expunge(sc); } - + @Override public void attachVolume(long volumeId, long vmId, long deviceId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setInstanceId(vmId); - volume.setDeviceId(deviceId); - volume.setUpdated(new Date()); - volume.setAttached(new Date()); - update(volumeId, volume); + VolumeVO volume = createForUpdate(volumeId); + volume.setInstanceId(vmId); + volume.setDeviceId(deviceId); + volume.setUpdated(new Date()); + volume.setAttached(new Date()); + update(volumeId, volume); } - + @Override public void detachVolume(long volumeId) { - VolumeVO volume = createForUpdate(volumeId); - volume.setInstanceId(null); + VolumeVO volume = createForUpdate(volumeId); + volume.setInstanceId(null); volume.setDeviceId(null); - volume.setUpdated(new Date()); - volume.setAttached(null); - update(volumeId, volume); + volume.setUpdated(new Date()); + volume.setAttached(null); + update(volumeId, volume); } - + @Override @DB - public HypervisorType getHypervisorType(long volumeId) { - /*lookup from cluster of pool*/ - Transaction txn = Transaction.currentTxn(); - PreparedStatement pstmt = null; + public HypervisorType getHypervisorType(long volumeId) { + /* lookup from cluster of pool */ + Transaction txn = Transaction.currentTxn(); + PreparedStatement pstmt = null; - try { - String sql = SELECT_HYPERTYPE_FROM_VOLUME; - pstmt = txn.prepareAutoCloseStatement(sql); - pstmt.setLong(1, volumeId); - ResultSet rs = pstmt.executeQuery(); - if (rs.next()) { + try { + String sql = SELECT_HYPERTYPE_FROM_VOLUME; + pstmt = txn.prepareAutoCloseStatement(sql); + pstmt.setLong(1, volumeId); + ResultSet rs = pstmt.executeQuery(); + if (rs.next()) { return HypervisorType.getType(rs.getString(1)); } - return HypervisorType.None; - } catch (SQLException e) { - throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e); - } catch (Throwable e) { - throw new CloudRuntimeException("Caught: " + SELECT_HYPERTYPE_FROM_VOLUME, e); - } - } - + return HypervisorType.None; + } catch (SQLException e) { + throw new CloudRuntimeException("DB Exception on: " + SELECT_HYPERTYPE_FROM_VOLUME, e); + } catch (Throwable e) { + throw new CloudRuntimeException("Caught: " + SELECT_HYPERTYPE_FROM_VOLUME, e); + } + } + @Override public ImageFormat getImageFormat(Long volumeId) { HypervisorType type = getHypervisorType(volumeId); - if ( type.equals(HypervisorType.KVM)) { + if (type.equals(HypervisorType.KVM)) { return ImageFormat.QCOW2; - } else if ( type.equals(HypervisorType.XenServer)) { + } else if (type.equals(HypervisorType.XenServer)) { return ImageFormat.VHD; - } else if ( type.equals(HypervisorType.VMware)) { + } else if (type.equals(HypervisorType.VMware)) { return ImageFormat.OVA; } else { s_logger.warn("Do not support hypervisor " + type.toString()); return null; } } - - public VolumeDaoImpl() { - AllFieldsSearch = createSearchBuilder(); - AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); + + public VolumeDaoImpl() { + AllFieldsSearch = createSearchBuilder(); + AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ); AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ); AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ); AllFieldsSearch.and("instanceId", AllFieldsSearch.entity().getInstanceId(), Op.EQ); @@ -264,33 +264,33 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ); AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ); AllFieldsSearch.done(); - + DetachedAccountIdSearch = createSearchBuilder(); DetachedAccountIdSearch.and("accountId", DetachedAccountIdSearch.entity().getAccountId(), Op.EQ); DetachedAccountIdSearch.and("destroyed", DetachedAccountIdSearch.entity().getState(), Op.NEQ); DetachedAccountIdSearch.and("instanceId", DetachedAccountIdSearch.entity().getInstanceId(), Op.NULL); DetachedAccountIdSearch.done(); - + TemplateZoneSearch = createSearchBuilder(); TemplateZoneSearch.and("template", TemplateZoneSearch.entity().getTemplateId(), Op.EQ); TemplateZoneSearch.and("zone", TemplateZoneSearch.entity().getDataCenterId(), Op.EQ); TemplateZoneSearch.done(); - + TotalSizeByPoolSearch = createSearchBuilder(SumCount.class); TotalSizeByPoolSearch.select("sum", Func.SUM, TotalSizeByPoolSearch.entity().getSize()); - TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[])null); + TotalSizeByPoolSearch.select("count", Func.COUNT, (Object[]) null); TotalSizeByPoolSearch.and("poolId", TotalSizeByPoolSearch.entity().getPoolId(), Op.EQ); TotalSizeByPoolSearch.and("removed", TotalSizeByPoolSearch.entity().getRemoved(), Op.NULL); TotalSizeByPoolSearch.and("state", TotalSizeByPoolSearch.entity().getState(), Op.NEQ); TotalSizeByPoolSearch.done(); - + ActiveTemplateSearch = createSearchBuilder(Long.class); ActiveTemplateSearch.and("pool", ActiveTemplateSearch.entity().getPoolId(), Op.EQ); ActiveTemplateSearch.and("template", ActiveTemplateSearch.entity().getTemplateId(), Op.EQ); ActiveTemplateSearch.and("removed", ActiveTemplateSearch.entity().getRemoved(), Op.NULL); ActiveTemplateSearch.select(null, Func.COUNT, null); ActiveTemplateSearch.done(); - + InstanceStatesSearch = createSearchBuilder(); InstanceStatesSearch.and("instance", InstanceStatesSearch.entity().getInstanceId(), Op.EQ); InstanceStatesSearch.and("states", InstanceStatesSearch.entity().getState(), Op.IN); @@ -315,24 +315,25 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol secondaryStorageSearch.and("path", secondaryStorageSearch.entity().getPath(), Op.NULL); secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL); secondaryStorageSearch.done(); - } + } - @Override @DB(txn=false) - public Pair getCountAndTotalByPool(long poolId) { + @Override + @DB(txn = false) + public Pair getCountAndTotalByPool(long poolId) { SearchCriteria sc = TotalSizeByPoolSearch.create(); sc.setParameters("poolId", poolId); List results = customSearch(sc, null); SumCount sumCount = results.get(0); return new Pair(sumCount.count, sumCount.sum); - } + } @Override - public Long countAllocatedVolumesForAccount(long accountId) { - SearchCriteria sc = CountByAccount.create(); + public Long countAllocatedVolumesForAccount(long accountId) { + SearchCriteria sc = CountByAccount.create(); sc.setParameters("account", accountId); - sc.setParameters("state", Volume.State.Destroy); + sc.setParameters("state", Volume.State.Destroy); return customSearch(sc, null).get(0); - } + } @Override public long primaryStorageUsedForAccount(long accountId) { @@ -358,55 +359,61 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol } } + public static class SumCount { + public long sum; + public long count; - public static class SumCount { - public long sum; - public long count; - public SumCount() { - } - } + public SumCount() { + } + } @Override public List listVolumesToBeDestroyed() { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("state", Volume.State.Destroy); - + return listBy(sc); } - @Override - public boolean updateState(com.cloud.storage.Volume.State currentState, - Event event, com.cloud.storage.Volume.State nextState, Volume vo, - Object data) { - - Long oldUpdated = vo.getUpdatedCount(); - Date oldUpdatedTime = vo.getUpdated(); - - SearchCriteria sc = AllFieldsSearch.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, "updated", new Date()); - - int rows = update((VolumeVO)vo, sc); - if (rows == 0 && s_logger.isDebugEnabled()) { - VolumeVO dbVol = findByIdIncludingRemoved(vo.getId()); - if (dbVol != null) { - StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=").append(dbVol.getUpdated()); - str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()).append("; updatedTime=").append(vo.getUpdated()); - str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated).append("; updatedTime=").append(oldUpdatedTime); - } else { - s_logger.debug("Unable to update volume: id=" + vo.getId() + ", as there is no such volume exists in the database anymore"); - } - } - return rows > 0; - } + @Override + public boolean updateState(com.cloud.storage.Volume.State currentState, Event event, + com.cloud.storage.Volume.State nextState, Volume vo, Object data) { + + Long oldUpdated = vo.getUpdatedCount(); + Date oldUpdatedTime = vo.getUpdated(); + + SearchCriteria sc = AllFieldsSearch.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, "updated", new Date()); + + int rows = update((VolumeVO) vo, sc); + if (rows == 0 && s_logger.isDebugEnabled()) { + VolumeVO dbVol = findByIdIncludingRemoved(vo.getId()); + if (dbVol != null) { + StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); + str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()) + .append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") + .append(dbVol.getUpdated()); + str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState) + .append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()) + .append("; updatedTime=").append(vo.getUpdated()); + str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState) + .append("; event=").append(event).append("; updatecount=").append(oldUpdated) + .append("; updatedTime=").append(oldUpdatedTime); + } else { + s_logger.debug("Unable to update volume: id=" + vo.getId() + + ", as there is no such volume exists in the database anymore"); + } + } + return rows > 0; + } @Override public List listPoolIdsByVolumeCount(long dcId, Long podId, Long clusterId, long accountId) { @@ -420,7 +427,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol pstmt.setLong(2, dcId); pstmt.setLong(3, podId); pstmt.setLong(4, clusterId); - + ResultSet rs = pstmt.executeQuery(); while (rs.next()) { result.add(rs.getLong(1)); @@ -432,8 +439,9 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol throw new CloudRuntimeException("Caught: " + ORDER_POOLS_NUMBER_OF_VOLUMES_FOR_ACCOUNT, e); } } - - @Override @DB(txn=false) + + @Override + @DB(txn = false) public Pair getNonDestroyedCountAndTotalByPool(long poolId) { SearchCriteria sc = TotalSizeByPoolSearch.create(); sc.setParameters("poolId", poolId); @@ -442,7 +450,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol SumCount sumCount = results.get(0); return new Pair(sumCount.count, sumCount.sum); } - + @Override @DB public boolean remove(Long id) { diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java b/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java index 39dda12345b..ccb276b47f9 100755 --- a/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeHostDao.java @@ -25,16 +25,17 @@ import com.cloud.storage.VolumeHostVO; import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface VolumeHostDao extends GenericDao, StateDao{ +public interface VolumeHostDao extends GenericDao, + StateDao { - VolumeHostVO findByHostVolume(long hostId, long volumeId); + VolumeHostVO findByHostVolume(long hostId, long volumeId); - VolumeHostVO findByVolumeId(long volumeId); + VolumeHostVO findByVolumeId(long volumeId); - List listBySecStorage(long sserverId); + List listBySecStorage(long sserverId); - List listDestroyed(long hostId); + List listDestroyed(long hostId); - VolumeHostVO findVolumeByZone(long zoneId, long volumeId); + VolumeHostVO findVolumeByZone(long zoneId, long volumeId); } diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java index 2fd39e6eeca..b731ebbeb4e 100755 --- a/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeHostDaoImpl.java @@ -35,7 +35,7 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.UpdateBuilder; @Component -@Local(value={VolumeHostDao.class}) +@Local(value = { VolumeHostDao.class }) public class VolumeHostDaoImpl extends GenericDaoBase implements VolumeHostDao { private static final Logger s_logger = Logger.getLogger(VolumeHostDaoImpl.class); protected final SearchBuilder HostVolumeSearch; @@ -44,7 +44,8 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem protected final SearchBuilder HostSearch; protected final SearchBuilder HostDestroyedSearch; protected final SearchBuilder updateStateSearch; - public VolumeHostDaoImpl(){ + + public VolumeHostDaoImpl() { HostVolumeSearch = createSearchBuilder(); HostVolumeSearch.and("host_id", HostVolumeSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostVolumeSearch.and("volume_id", HostVolumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ); @@ -58,7 +59,7 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem ZoneVolumeSearch.done(); HostSearch = createSearchBuilder(); - HostSearch.and("host_id", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); + HostSearch.and("host_id", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostSearch.and("destroyed", HostSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); HostSearch.done(); @@ -70,8 +71,8 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem HostDestroyedSearch = createSearchBuilder(); HostDestroyedSearch.and("host_id", HostDestroyedSearch.entity().getHostId(), SearchCriteria.Op.EQ); HostDestroyedSearch.and("destroyed", HostDestroyedSearch.entity().getDestroyed(), SearchCriteria.Op.EQ); - HostDestroyedSearch.done(); - + HostDestroyedSearch.done(); + updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -79,8 +80,6 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem updateStateSearch.done(); } - - @Override public VolumeHostVO findByHostVolume(long hostId, long volumeId) { SearchCriteria sc = HostVolumeSearch.create(); @@ -88,7 +87,7 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem sc.setParameters("volume_id", volumeId); sc.setParameters("destroyed", false); return findOneIncludingRemovedBy(sc); - } + } @Override public VolumeHostVO findVolumeByZone(long volumeId, long zoneId) { @@ -107,8 +106,6 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem return findOneBy(sc); } - - @Override public List listBySecStorage(long ssHostId) { SearchCriteria sc = HostSearch.create(); @@ -118,7 +115,7 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem } @Override - public List listDestroyed(long hostId){ + public List listDestroyed(long hostId) { SearchCriteria sc = HostDestroyedSearch.create(); sc.setParameters("host_id", hostId); sc.setParameters("destroyed", true); @@ -126,13 +123,11 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem } @Override - public boolean updateState(State currentState, Event event, - State nextState, DataObjectInStore vo, Object data) { + public boolean updateState(State currentState, Event event, State nextState, DataObjectInStore vo, Object data) { VolumeHostVO volHost = (VolumeHostVO) vo; Long oldUpdated = volHost.getUpdatedCount(); Date oldUpdatedTime = volHost.getUpdated(); - - + SearchCriteria sc = updateStateSearch.create(); sc.setParameters("id", volHost.getId()); sc.setParameters("state", currentState); @@ -149,14 +144,18 @@ public class VolumeHostDaoImpl extends GenericDaoBase implem VolumeHostVO dbVol = findByIdIncludingRemoved(volHost.getId()); if (dbVol != null) { StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()).append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") + str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()) + .append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") .append(dbVol.getUpdated()); - str.append(": New Data={id=").append(volHost.getId()).append("; state=").append(nextState).append("; event=").append(event).append("; updatecount=").append(volHost.getUpdatedCount()) + str.append(": New Data={id=").append(volHost.getId()).append("; state=").append(nextState) + .append("; event=").append(event).append("; updatecount=").append(volHost.getUpdatedCount()) .append("; updatedTime=").append(volHost.getUpdated()); - str.append(": stale Data={id=").append(volHost.getId()).append("; state=").append(currentState).append("; event=").append(event).append("; updatecount=").append(oldUpdated) + str.append(": stale Data={id=").append(volHost.getId()).append("; state=").append(currentState) + .append("; event=").append(event).append("; updatecount=").append(oldUpdated) .append("; updatedTime=").append(oldUpdatedTime); } else { - s_logger.debug("Unable to update objectIndatastore: id=" + volHost.getId() + ", as there is no such object exists in the database anymore"); + s_logger.debug("Unable to update objectIndatastore: id=" + volHost.getId() + + ", as there is no such object exists in the database anymore"); } } return rows > 0; 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 index f8232b8987a..f244a0371b7 100644 --- 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 @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.storage.cache.allocator; +import java.util.Collections; import java.util.List; import javax.inject.Inject; @@ -30,27 +31,25 @@ import org.springframework.stereotype.Component; import com.cloud.storage.ScopeType; -import edu.emory.mathcs.backport.java.util.Collections; - @Component public class StorageCacheRandomAllocator implements StorageCacheAllocator { - private static final Logger s_logger = Logger - .getLogger(StorageCacheRandomAllocator.class); + private static final Logger s_logger = Logger.getLogger(StorageCacheRandomAllocator.class); @Inject DataStoreManager dataStoreMgr; + @Override public DataStore getCacheStore(Scope scope) { if (scope.getScopeType() != ScopeType.ZONE) { s_logger.debug("Can only support zone wide cache storage"); return null; } - + List cacheStores = dataStoreMgr.getImageCacheStores(scope); if (cacheStores.size() <= 0) { s_logger.debug("Can't find cache storage in zone: " + scope.getScopeId()); return null; } - + Collections.shuffle(cacheStores); return cacheStores.get(0); } 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 index d2895fdf377..cb5ea106fed 100644 --- 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 @@ -39,16 +39,14 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.cache.allocator.StorageCacheAllocator; -import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.log4j.Logger; import com.cloud.utils.component.Manager; +import com.cloud.utils.exception.CloudRuntimeException; public class StorageCacheManagerImpl implements StorageCacheManager, Manager { - private static final Logger s_logger = Logger - .getLogger(StorageCacheManagerImpl.class); + private static final Logger s_logger = Logger.getLogger(StorageCacheManagerImpl.class); @Inject List storageCacheAllocator; @Inject @@ -120,10 +118,9 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return true; } - - private class CreateCacheObjectContext extends AsyncRpcConext { final AsyncCallFuture future; + /** * @param callback */ @@ -134,48 +131,47 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { } - @Override - public DataObject createCacheObject(DataObject data, Scope scope) { - DataStore cacheStore = this.getCacheStorage(scope); - DataObjectInStore obj = objectInStoreMgr.findObject(data, cacheStore); - if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready) { - s_logger.debug("there is already one in the cache store"); - return objectInStoreMgr.get(data, cacheStore); - } + @Override + public DataObject createCacheObject(DataObject data, Scope scope) { + DataStore cacheStore = this.getCacheStorage(scope); + DataObjectInStore obj = objectInStoreMgr.findObject(data, cacheStore); + if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready) { + s_logger.debug("there is already one in the cache store"); + return objectInStoreMgr.get(data, cacheStore); + } - //TODO: consider multiple thread to create - DataObject objOnCacheStore = cacheStore.create(data); + DataObject objOnCacheStore = cacheStore.create(data); - AsyncCallFuture future = new AsyncCallFuture(); - CopyCommandResult result = null; - try { - objOnCacheStore.processEvent(Event.CreateOnlyRequested); + AsyncCallFuture future = new AsyncCallFuture(); + CopyCommandResult result = null; + try { + objOnCacheStore.processEvent(Event.CreateOnlyRequested); - dataMotionSvr.copyAsync(data, objOnCacheStore, future); - result = future.get(); + dataMotionSvr.copyAsync(data, objOnCacheStore, future); + result = future.get(); - if (result.isFailed()) { - objOnCacheStore.processEvent(Event.OperationFailed); - } else { - objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); - return objOnCacheStore; - } + if (result.isFailed()) { + objOnCacheStore.processEvent(Event.OperationFailed); + } else { + objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); + return objOnCacheStore; + } } catch (InterruptedException e) { s_logger.debug("create cache storage failed: " + e.toString()); + throw new CloudRuntimeException(e); } catch (ExecutionException e) { s_logger.debug("create cache storage failed: " + e.toString()); - } catch (Exception e) { - s_logger.debug("create cache storage failed: " + e.toString()); + throw new CloudRuntimeException(e); } finally { if (result == null) { objOnCacheStore.processEvent(Event.OperationFailed); } } - return null; - } + return null; + } - @Override + @Override public DataObject getCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); @@ -183,12 +179,13 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return objOnCacheStore; } - protected Void createCacheObjectCallBack(AsyncCallbackDispatcher callback, - CreateCacheObjectContext context) { - AsyncCallFuture future = context.future; - future.complete(callback.getResult()); - return null; - } + protected Void createCacheObjectCallBack( + AsyncCallbackDispatcher callback, + CreateCacheObjectContext context) { + AsyncCallFuture future = context.future; + future.complete(callback.getResult()); + return null; + } @Override public boolean deleteCacheObject(DataObject data) { 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 index 65beb40c475..a01d2d30139 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -23,30 +23,29 @@ import java.util.Map; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; 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.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; -import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.StorageCacheManager; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataObjectType; @@ -56,11 +55,9 @@ import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; -import com.cloud.storage.ImageStore; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.VolumeManager; @@ -77,8 +74,7 @@ import com.cloud.utils.exception.CloudRuntimeException; @Component public class AncientDataMotionStrategy implements DataMotionStrategy { - private static final Logger s_logger = Logger - .getLogger(AncientDataMotionStrategy.class); + private static final Logger s_logger = Logger.getLogger(AncientDataMotionStrategy.class); @Inject EndPointSelector selector; @Inject @@ -107,8 +103,10 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { DataStoreManager dataStoreMgr; @Inject TemplateDataStoreDao templateStoreDao; - @Inject DiskOfferingDao diskOfferingDao; - @Inject VMTemplatePoolDao templatePoolDao; + @Inject + DiskOfferingDao diskOfferingDao; + @Inject + VMTemplatePoolDao templatePoolDao; @Inject VolumeManager volumeMgr; @Inject @@ -125,7 +123,6 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return false; } - protected boolean needCacheStorage(DataObject srcData, DataObject destData) { DataTO srcTO = srcData.getTO(); DataTO destTO = destData.getTO(); @@ -140,9 +137,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } return true; } - + private Scope getZoneScope(Scope destScope) { - ZoneScope zoneScope = null; + ZoneScope zoneScope = null; if (destScope instanceof ClusterScope) { ClusterScope clusterScope = (ClusterScope) destScope; zoneScope = new ZoneScope(clusterScope.getZoneId()); @@ -150,14 +147,15 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { HostScope hostScope = (HostScope) destScope; zoneScope = new ZoneScope(hostScope.getZoneId()); } else { - zoneScope = (ZoneScope)destScope; + zoneScope = (ZoneScope) destScope; } return zoneScope; } protected Answer copyObject(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.PrimaryStorageDownloadWait.toString()); - int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); + int _primaryStorageDownloadWait = NumbersUtil.parseInt(value, + Integer.parseInt(Config.PrimaryStorageDownloadWait.getDefaultValue())); Answer answer = null; DataObject cacheData = null; try { @@ -193,7 +191,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected DataObject cacheSnapshotChain(SnapshotInfo snapshot) { DataObject leafData = null; - while(snapshot != null) { + while (snapshot != null) { DataObject cacheData = cacheMgr.createCacheObject(snapshot, snapshot.getDataStore().getScope()); if (leafData == null) { leafData = cacheData; @@ -208,11 +206,10 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) { - SnapshotInfo snapshot = (SnapshotInfo)snapObj; + SnapshotInfo snapshot = (SnapshotInfo) snapObj; StoragePool pool = (StoragePool) volObj.getDataStore(); - String basicErrMsg = "Failed to create volume from " - + snapshot.getName() + " on pool " + pool; + String basicErrMsg = "Failed to create volume from " + snapshot.getName() + " on pool " + pool; DataStore store = snapObj.getDataStore(); DataStoreTO storTO = store.getTO(); DataObject srcData = snapObj; @@ -221,23 +218,21 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { srcData = cacheSnapshotChain(snapshot); } - String value = configDao - .getValue(Config.CreateVolumeFromSnapshotWait.toString()); + String value = configDao.getValue(Config.CreateVolumeFromSnapshotWait.toString()); int _createVolumeFromSnapshotWait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CreateVolumeFromSnapshotWait - .getDefaultValue())); + Integer.parseInt(Config.CreateVolumeFromSnapshotWait.getDefaultValue())); CopyCommand cmd = new CopyCommand(srcData.getTO(), volObj.getTO(), _createVolumeFromSnapshotWait); EndPoint ep = selector.select(snapObj, volObj); Answer answer = ep.sendMessage(cmd); - return answer; + return answer; } catch (Exception e) { s_logger.error(basicErrMsg, e); throw new CloudRuntimeException(basicErrMsg); } finally { if (!(storTO instanceof NfsTO)) { - deleteSnapshotCacheChain((SnapshotInfo)srcData); + deleteSnapshotCacheChain((SnapshotInfo) srcData); } } } @@ -256,86 +251,82 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected Answer copyVolumeBetweenPools(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.CopyVolumeWait.key()); - int _copyvolumewait = NumbersUtil.parseInt(value, - Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); + int _copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); Scope destScope = getZoneScope(destData.getDataStore().getScope()); DataStore cacheStore = cacheMgr.getCacheStorage(destScope); if (cacheStore == null) { - //need to find a nfs image store, assuming that can't copy volume directly to s3 - ImageStoreEntity imageStore = (ImageStoreEntity)this.dataStoreMgr.getImageStore(destScope.getScopeId()); - if (!imageStore.getProtocol().equalsIgnoreCase("nfs")) { - s_logger.debug("can't find a nfs image store"); - return null; - } + // need to find a nfs image store, assuming that can't copy volume + // directly to s3 + ImageStoreEntity imageStore = (ImageStoreEntity) this.dataStoreMgr.getImageStore(destScope.getScopeId()); + if (!imageStore.getProtocol().equalsIgnoreCase("nfs")) { + s_logger.debug("can't find a nfs image store"); + return null; + } - DataObject objOnImageStore = imageStore.create(srcData); - objOnImageStore.processEvent(Event.CreateOnlyRequested); + DataObject objOnImageStore = imageStore.create(srcData); + objOnImageStore.processEvent(Event.CreateOnlyRequested); - Answer answer = this.copyObject(srcData, objOnImageStore); - if (answer == null || !answer.getResult()) { - if (answer != null) { - s_logger.debug("copy to image store failed: " + answer.getDetails()); - } - objOnImageStore.processEvent(Event.OperationFailed); - imageStore.delete(objOnImageStore); - return answer; - } + Answer answer = this.copyObject(srcData, objOnImageStore); + if (answer == null || !answer.getResult()) { + if (answer != null) { + s_logger.debug("copy to image store failed: " + answer.getDetails()); + } + objOnImageStore.processEvent(Event.OperationFailed); + imageStore.delete(objOnImageStore); + return answer; + } - objOnImageStore.processEvent(Event.OperationSuccessed, answer); + objOnImageStore.processEvent(Event.OperationSuccessed, answer); - objOnImageStore.processEvent(Event.CopyingRequested); + objOnImageStore.processEvent(Event.CopyingRequested); - CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), destData.getTO(), _copyvolumewait); - EndPoint ep = selector.select(objOnImageStore, destData); - answer = ep.sendMessage(cmd); - - if (answer == null || !answer.getResult()) { - if (answer != null) { - s_logger.debug("copy to primary store failed: " + answer.getDetails()); - } - objOnImageStore.processEvent(Event.OperationFailed); - imageStore.delete(objOnImageStore); - return answer; - } - - objOnImageStore.processEvent(Event.OperationSuccessed); - imageStore.delete(objOnImageStore); - return answer; + CopyCommand cmd = new CopyCommand(objOnImageStore.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(objOnImageStore, destData); + answer = ep.sendMessage(cmd); + + if (answer == null || !answer.getResult()) { + if (answer != null) { + s_logger.debug("copy to primary store failed: " + answer.getDetails()); + } + objOnImageStore.processEvent(Event.OperationFailed); + imageStore.delete(objOnImageStore); + return answer; + } + + objOnImageStore.processEvent(Event.OperationSuccessed); + imageStore.delete(objOnImageStore); + return answer; } else { - DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); - CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); - EndPoint ep = selector.select(cacheData, destData); - Answer answer = ep.sendMessage(cmd); - return answer; + DataObject cacheData = cacheMgr.createCacheObject(srcData, destScope); + CopyCommand cmd = new CopyCommand(cacheData.getTO(), destData.getTO(), _copyvolumewait); + EndPoint ep = selector.select(cacheData, destData); + Answer answer = ep.sendMessage(cmd); + return answer; } } @Override - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { + public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { Answer answer = null; String errMsg = null; try { - if (srcData.getType() == DataObjectType.SNAPSHOT - && destData.getType() == DataObjectType.VOLUME) { - answer = copyVolumeFromSnapshot(srcData, destData); - } else if (srcData.getType() == DataObjectType.SNAPSHOT - && destData.getType() == DataObjectType.TEMPLATE) { - answer = createTemplateFromSnapshot(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 && destData.getDataStore().getRole() == DataStoreRole.Primary) { - answer = copyVolumeBetweenPools(srcData, destData); - } else if (srcData.getType() == DataObjectType.SNAPSHOT && - destData.getType() == DataObjectType.SNAPSHOT) { - answer = copySnapshot(srcData, destData); + if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.VOLUME) { + answer = copyVolumeFromSnapshot(srcData, destData); + } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.TEMPLATE) { + answer = createTemplateFromSnapshot(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 + && destData.getDataStore().getRole() == DataStoreRole.Primary) { + answer = copyVolumeBetweenPools(srcData, destData); + } else if (srcData.getType() == DataObjectType.SNAPSHOT && destData.getType() == DataObjectType.SNAPSHOT) { + answer = copySnapshot(srcData, destData); } else { - answer = copyObject(srcData, destData); + answer = copyObject(srcData, destData); } if (answer != null && !answer.getResult()) { @@ -352,19 +343,14 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } @DB - protected Answer createTemplateFromSnapshot(DataObject srcData, - DataObject destData) { + protected Answer createTemplateFromSnapshot(DataObject srcData, DataObject destData) { - String value = configDao - .getValue(Config.CreatePrivateTemplateFromSnapshotWait - .toString()); - int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt( - value, Integer - .parseInt(Config.CreatePrivateTemplateFromSnapshotWait - .getDefaultValue())); + String value = configDao.getValue(Config.CreatePrivateTemplateFromSnapshotWait.toString()); + int _createprivatetemplatefromsnapshotwait = NumbersUtil.parseInt(value, + Integer.parseInt(Config.CreatePrivateTemplateFromSnapshotWait.getDefaultValue())); if (needCacheStorage(srcData, destData)) { - SnapshotInfo snapshot = (SnapshotInfo)srcData; + SnapshotInfo snapshot = (SnapshotInfo) srcData; srcData = cacheSnapshotChain(snapshot); } @@ -376,7 +362,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected Answer copySnapshot(DataObject srcData, DataObject destData) { String value = configDao.getValue(Config.BackupSnapshotWait.toString()); - int _backupsnapshotwait = NumbersUtil.parseInt(value, Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); + int _backupsnapshotwait = NumbersUtil.parseInt(value, + Integer.parseInt(Config.BackupSnapshotWait.getDefaultValue())); DataObject cacheData = null; Answer answer = null; 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 index 8db878afe12..22de0b25279 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionServiceImpl.java @@ -42,17 +42,13 @@ public class DataMotionServiceImpl implements DataMotionService { List strategies; @Override - public void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { if (srcData.getDataStore().getDriver().canCopy(srcData, destData)) { - srcData.getDataStore().getDriver() - .copyAsync(srcData, destData, callback); + srcData.getDataStore().getDriver().copyAsync(srcData, destData, callback); return; - } else if (destData.getDataStore().getDriver() - .canCopy(srcData, destData)) { - destData.getDataStore().getDriver() - .copyAsync(srcData, destData, callback); + } else if (destData.getDataStore().getDriver().canCopy(srcData, destData)) { + destData.getDataStore().getDriver().copyAsync(srcData, destData, callback); return; } @@ -66,8 +62,8 @@ public class DataMotionServiceImpl implements DataMotionService { } @Override - public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, - Host srcHost, Host destHost, AsyncCompletionCallback callback) { + public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, + AsyncCompletionCallback callback) { for (DataMotionStrategy strategy : strategies) { if (strategy.canHandle(volumeMap, srcHost, destHost)) { strategy.copyAsync(volumeMap, vmTo, srcHost, destHost, callback); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java index 52c79e6da6b..e369c1c033e 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateDataFactoryImpl.java @@ -33,15 +33,13 @@ import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; @Component public class TemplateDataFactoryImpl implements TemplateDataFactory { - private static final Logger s_logger = Logger - .getLogger(TemplateDataFactoryImpl.class); + private static final Logger s_logger = Logger.getLogger(TemplateDataFactoryImpl.class); @Inject VMTemplateDao imageDataDao; @Inject @@ -50,11 +48,12 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory { VMTemplatePoolDao templatePoolDao; @Inject TemplateDataStoreDao templateStoreDao; + @Override public TemplateInfo getTemplate(long templateId, DataStore store) { VMTemplateVO templ = imageDataDao.findById(templateId); if (store == null) { - TemplateObject tmpl = TemplateObject.getTemplate(templ, null); + TemplateObject tmpl = TemplateObject.getTemplate(templ, null); return tmpl; } // verify if the given input parameters are consistent with our db data. @@ -75,17 +74,15 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory { s_logger.debug("template " + templateId + " is not in store:" + store.getId() + ", type:" + store.getRole()); } - TemplateObject tmpl = TemplateObject.getTemplate(templ, store); + TemplateObject tmpl = TemplateObject.getTemplate(templ, store); return tmpl; } - @Override public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole) { - VMTemplateVO templ = imageDataDao.findById(templateId); TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId, storeRole); DataStore store = null; - if ( tmplStore != null ){ + if (tmplStore != null) { store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole); } return this.getTemplate(templateId, store); @@ -93,16 +90,14 @@ public class TemplateDataFactoryImpl implements TemplateDataFactory { @Override public TemplateInfo getTemplate(long templateId, DataStoreRole storeRole, Long zoneId) { - VMTemplateVO templ = imageDataDao.findById(templateId); TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplateZone(templateId, zoneId, storeRole); DataStore store = null; - if ( tmplStore != null ){ + if (tmplStore != null) { store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), storeRole); } return this.getTemplate(templateId, store); } - @Override public TemplateInfo getTemplate(DataObject obj, DataStore store) { return this.getTemplate(obj.getId(), store); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index c4d04fb9910..a0cbc27b1b2 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -28,9 +28,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; @@ -40,10 +37,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; @@ -61,6 +58,8 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.DeleteTemplateCommand; @@ -68,11 +67,9 @@ import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; @@ -92,7 +89,6 @@ import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; @Component @@ -134,7 +130,8 @@ public class TemplateServiceImpl implements TemplateService { VolumeDao _volumeDao; @Inject TemplateDataFactory _templateFactory; - @Inject VMTemplatePoolDao _tmpltPoolDao; + @Inject + VMTemplatePoolDao _tmpltPoolDao; @Inject EndPointSelector _epSelector; @Inject @@ -142,12 +139,12 @@ public class TemplateServiceImpl implements TemplateService { @Inject TemplateManager _tmpltMgr; - class TemplateOpContext extends AsyncRpcConext { final TemplateObject template; final AsyncCallFuture future; + public TemplateOpContext(AsyncCompletionCallback callback, TemplateObject template, - AsyncCallFuture future) { + AsyncCallFuture future) { super(callback); this.template = template; this.future = future; @@ -161,22 +158,21 @@ public class TemplateServiceImpl implements TemplateService { return future; } - } @Override - public void createTemplateAsync( - TemplateInfo template, DataStore store, AsyncCompletionCallback callback) { + public void createTemplateAsync(TemplateInfo template, DataStore store, + AsyncCompletionCallback callback) { // persist template_store_ref entry - TemplateObject templateOnStore = (TemplateObject)store.create(template); + TemplateObject templateOnStore = (TemplateObject) store.create(template); // update template_store_ref and template state - try{ + try { templateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested); } catch (Exception e) { TemplateApiResult result = new TemplateApiResult(templateOnStore); result.setResult(e.toString()); result.setSuccess(false); - if ( callback != null ){ + if (callback != null) { callback.complete(result); } return; @@ -203,8 +199,8 @@ public class TemplateServiceImpl implements TemplateService { List availHypers = _clusterDao.getAvailableHypervisorInZone(store.getScope().getScopeId()); if (availHypers.isEmpty()) { /* - * This is for cloudzone, local secondary storage resource - * started before cluster created + * This is for cloudzone, local secondary storage resource started + * before cluster created */ availHypers.add(HypervisorType.KVM); } @@ -216,7 +212,8 @@ public class TemplateServiceImpl implements TemplateService { for (VMTemplateVO template : toBeDownloaded) { if (availHypers.contains(template.getHypervisorType())) { // only download sys template applicable for current hypervisor - TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao + .findByStoreTemplate(store.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { TemplateInfo tmplt = _templateFactory.getTemplate(template.getId(), DataStoreRole.Image); createTemplateAsync(tmplt, store, null); @@ -229,16 +226,15 @@ public class TemplateServiceImpl implements TemplateService { public void handleSysTemplateDownload(HypervisorType hostHyper, Long dcId) { Set toBeDownloaded = new HashSet(); List stores = _storeMgr.getImageStoresByScope(new ZoneScope(dcId)); - if (stores == null || stores.isEmpty()){ + if (stores == null || stores.isEmpty()) { return; } - /*Download all the templates in zone with the same hypervisortype*/ - for ( DataStore store : stores) { + /* Download all the templates in zone with the same hypervisortype */ + for (DataStore store : stores) { List rtngTmplts = _templateDao.listAllSystemVMTemplates(); List defaultBuiltin = _templateDao.listDefaultBuiltinTemplates(); - for (VMTemplateVO rtngTmplt : rtngTmplts) { if (rtngTmplt.getHypervisorType() == hostHyper) { toBeDownloaded.add(rtngTmplt); @@ -251,8 +247,9 @@ public class TemplateServiceImpl implements TemplateService { } } - for (VMTemplateVO template: toBeDownloaded) { - TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao.findByStoreTemplate(store.getId(), template.getId()); + for (VMTemplateVO template : toBeDownloaded) { + TemplateDataStoreVO tmpltHost = _vmTemplateStoreDao + .findByStoreTemplate(store.getId(), template.getId()); if (tmpltHost == null || tmpltHost.getState() != ObjectInDataStoreStateMachine.State.Ready) { TemplateInfo tmplt = _templateFactory.getTemplate(template.getId(), DataStoreRole.Image); createTemplateAsync(tmplt, store, null); @@ -277,11 +274,10 @@ public class TemplateServiceImpl implements TemplateService { Set toBeDownloaded = new HashSet(); List allTemplates = null; - if (zoneId == null){ + if (zoneId == null) { // region wide store allTemplates = _templateDao.listAllActive(); - } - else{ + } else { // zone wide store allTemplates = _templateDao.listAllInZone(zoneId); } @@ -319,7 +315,8 @@ public class TemplateServiceImpl implements TemplateService { } if (tmpltInfo.isCorrupted()) { tmpltStore.setDownloadState(Status.DOWNLOAD_ERROR); - String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + " is corrupted on secondary storage " + tmpltStore.getId(); + String msg = "Template " + tmplt.getName() + ":" + tmplt.getId() + + " is corrupted on secondary storage " + tmpltStore.getId(); tmpltStore.setErrorString(msg); s_logger.info("msg"); if (tmplt.getUrl() == null) { @@ -344,11 +341,14 @@ public class TemplateServiceImpl implements TemplateService { // set template to ready state if (tmplt.getState() != TemplateState.Ready) { try { - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, _templateDao); - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, + _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, + _templateDao); } catch (NoTransitionException e) { // non fatal though - s_logger.debug("failed to update template " + tmplt.getUniqueName() + " state to Ready", e); + s_logger.debug( + "failed to update template " + tmplt.getUniqueName() + " state to Ready", e); } } @@ -360,17 +360,19 @@ public class TemplateServiceImpl implements TemplateService { tmpltInfo.getSize() - UriUtils.getRemoteSize(tmplt.getUrl())); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, null, e.getMessage(), e.getMessage()); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, zoneId, null, + e.getMessage(), e.getMessage()); } finally { - _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId).getDomainId(), - com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); + _resourceLimitMgr.recalculateResourceCount(accountId, _accountMgr.getAccount(accountId) + .getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage + .getOrdinal()); } } } _vmTemplateStoreDao.update(tmpltStore.getId(), tmpltStore); } else { - tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, - tmpltInfo.getInstallPath(), tmplt.getUrl()); + tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, + null, null, null, tmpltInfo.getInstallPath(), tmplt.getUrl()); tmpltStore.setSize(tmpltInfo.getSize()); tmpltStore.setPhysicalSize(tmpltInfo.getPhysicalSize()); tmpltStore.setDataStoreRole(store.getRole()); @@ -385,8 +387,10 @@ public class TemplateServiceImpl implements TemplateService { // set template to ready state if (tmplt.getState() != TemplateState.Ready) { try { - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, _templateDao); - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, + _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, + _templateDao); } catch (NoTransitionException e) { // non fatal though s_logger.debug("failed to update template " + tmplt.getUniqueName() + " state to Ready", e); @@ -429,7 +433,8 @@ public class TemplateServiceImpl implements TemplateService { continue; } if (availHypers.contains(tmplt.getHypervisorType())) { - s_logger.info("Downloading template " + tmplt.getUniqueName() + " to image store " + store.getName()); + s_logger.info("Downloading template " + tmplt.getUniqueName() + " to image store " + + store.getName()); associateTemplateToZone(tmplt.getId(), zoneId); TemplateInfo tmpl = _templateFactory.getTemplate(tmplt.getId(), DataStoreRole.Image); createTemplateAsync(tmpl, store, null); @@ -437,19 +442,22 @@ public class TemplateServiceImpl implements TemplateService { } } - for (String uniqueName : templateInfos.keySet()) { + for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); if (_tmpltMgr.templateIsDeleteable(tInfo.getId())) { - //TODO: we cannot directly call deleteTemplateSync here to reuse delete logic since in this case, our db does not have this template at all. - VMTemplateVO template = _templateDao.findById(tInfo.getId()); - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), null, null); + // TODO: we cannot directly call deleteTemplateSync here to + // reuse delete logic since in this case, our db does not have + // this template at all. + DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), + null, null); EndPoint ep = _epSelector.select(store); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { s_logger.info("Failed to deleted template at store: " + store.getName()); } else { - String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + storeId; + String description = "Deleted template " + tInfo.getTemplateName() + " on secondary storage " + + storeId; s_logger.info(description); } @@ -458,17 +466,16 @@ public class TemplateServiceImpl implements TemplateService { } - - // persist entry in template_zone_ref table. zoneId can be empty for region-wide image store, in that case, + // persist entry in template_zone_ref table. zoneId can be empty for + // region-wide image store, in that case, // we will associate the template to all the zones. - private void associateTemplateToZone(long templateId, Long zoneId){ + private void associateTemplateToZone(long templateId, Long zoneId) { List dcs = new ArrayList(); - if (zoneId != null ){ + if (zoneId != null) { dcs.add(zoneId); - } - else{ + } else { List zones = _dcDao.listAll(); - for (DataCenterVO zone : zones){ + for (DataCenterVO zone : zones) { dcs.add(zone.getId()); } } @@ -484,13 +491,12 @@ public class TemplateServiceImpl implements TemplateService { } } - private Map listTemplate(DataStore ssStore) { ListTemplateCommand cmd = new ListTemplateCommand(ssStore.getTO()); EndPoint ep = _epSelector.select(ssStore); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { - ListTemplateAnswer tanswer = (ListTemplateAnswer)answer; + ListTemplateAnswer tanswer = (ListTemplateAnswer) answer; return tanswer.getTemplateInfo(); } else { if (s_logger.isDebugEnabled()) { @@ -501,7 +507,6 @@ public class TemplateServiceImpl implements TemplateService { return null; } - protected Void createTemplateCallback(AsyncCallbackDispatcher callback, TemplateOpContext context) { TemplateObject template = context.getTemplate(); @@ -511,7 +516,7 @@ public class TemplateServiceImpl implements TemplateService { if (callbackResult.isFailed()) { template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); result.setResult(callbackResult.getResult()); - if ( parentCallback != null ){ + if (parentCallback != null) { parentCallback.complete(result); } return null; @@ -521,21 +526,20 @@ public class TemplateServiceImpl implements TemplateService { template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); } catch (Exception e) { result.setResult(e.toString()); - if ( parentCallback != null ){ + if (parentCallback != null) { parentCallback.complete(result); } return null; } - if (parentCallback != null){ + if (parentCallback != null) { parentCallback.complete(result); } return null; } @Override - public AsyncCallFuture deleteTemplateAsync( - TemplateInfo template) { + public AsyncCallFuture deleteTemplateAsync(TemplateInfo template) { TemplateObject to = (TemplateObject) template; // update template_store_ref status to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); @@ -549,14 +553,15 @@ public class TemplateServiceImpl implements TemplateService { return future; } - public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, TemplateOpContext context) { + public Void deleteTemplateCallback(AsyncCallbackDispatcher callback, + TemplateOpContext context) { CommandResult result = callback.getResult(); TemplateObject vo = context.getTemplate(); - if (result.isSuccess()) { + if (result.isSuccess()) { vo.processEvent(Event.OperationSuccessed); } else { vo.processEvent(Event.OperationFailed); - } + } TemplateApiResult apiResult = new TemplateApiResult(vo); apiResult.setResult(result.getResult()); apiResult.setSuccess(result.isSuccess()); @@ -564,12 +569,13 @@ public class TemplateServiceImpl implements TemplateService { return null; } - private AsyncCallFuture copyAsync(DataObject source, TemplateInfo template, DataStore store){ + private AsyncCallFuture copyAsync(DataObject source, TemplateInfo template, DataStore store) { AsyncCallFuture future = new AsyncCallFuture(); DataObject templateOnStore = store.create(template); templateOnStore.processEvent(Event.CreateOnlyRequested); - TemplateOpContext context = new TemplateOpContext(null, (TemplateObject) templateOnStore, future); + TemplateOpContext context = new TemplateOpContext(null, + (TemplateObject) templateOnStore, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().copyTemplateCallBack(null, null)).setContext(context); _motionSrv.copyAsync(source, templateOnStore, caller); @@ -577,14 +583,14 @@ public class TemplateServiceImpl implements TemplateService { } @Override - public AsyncCallFuture createTemplateFromSnapshotAsync( - SnapshotInfo snapshot, TemplateInfo template, DataStore store) { + public AsyncCallFuture createTemplateFromSnapshotAsync(SnapshotInfo snapshot, + TemplateInfo template, DataStore store) { return copyAsync(snapshot, template, store); } @Override - public AsyncCallFuture createTemplateFromVolumeAsync( - VolumeInfo volume, TemplateInfo template, DataStore store) { + public AsyncCallFuture createTemplateFromVolumeAsync(VolumeInfo volume, TemplateInfo template, + DataStore store) { return copyAsync(volume, template, store); } @@ -595,7 +601,7 @@ public class TemplateServiceImpl implements TemplateService { @Override public AsyncCallFuture prepareTemplateOnPrimary(TemplateInfo srcTemplate, StoragePool pool) { - return copyAsync(srcTemplate, srcTemplate, (DataStore)pool); + return copyAsync(srcTemplate, srcTemplate, (DataStore) pool); } protected Void copyTemplateCallBack(AsyncCallbackDispatcher callback, @@ -623,29 +629,29 @@ public class TemplateServiceImpl implements TemplateService { return null; } - @Override - public void addSystemVMTemplatesToSecondary(DataStore store){ + public void addSystemVMTemplatesToSecondary(DataStore store) { long storeId = store.getId(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); - for ( VMTemplateVO tmplt : rtngTmplts ) { + for (VMTemplateVO tmplt : rtngTmplts) { // set template ready state - if ( tmplt.getState() != TemplateState.Ready ){ + if (tmplt.getState() != TemplateState.Ready) { try { - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, - _templateDao); - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, - _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, _templateDao); + imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, _templateDao); } catch (NoTransitionException e) { // non fatal though s_logger.debug("failed to update system vm template state to Ready", e); } } TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); - if ( tmpltStore == null ) { - tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, null, null, TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, tmplt.getUrl()); + if (tmpltStore == null) { + tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, + null, null, TemplateConstants.DEFAULT_SYSTEM_VM_TEMPLATE_PATH + tmplt.getId() + File.separator, + tmplt.getUrl()); tmpltStore.setSize(0L); - tmpltStore.setPhysicalSize(0); // no size information for pre-seeded system vm templates + tmpltStore.setPhysicalSize(0); // no size information for + // pre-seeded system vm templates tmpltStore.setDataStoreRole(store.getRole()); _vmTemplateStoreDao.persist(tmpltStore); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java index d8708308cef..f41416baf90 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java @@ -27,8 +27,7 @@ import com.cloud.utils.fsm.StateMachine2; @Component public class ImageDataManagerImpl implements ImageDataManager { - private final StateMachine2 - stateMachine = new StateMachine2(); + private final StateMachine2 stateMachine = new StateMachine2(); public ImageDataManagerImpl() { stateMachine.addTransition(TemplateState.Allocated, TemplateEvent.CreateRequested, TemplateState.Creating); @@ -41,7 +40,8 @@ public class ImageDataManagerImpl implements ImageDataManager { stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.DestroyRequested, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationFailed, TemplateState.Destroying); stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationSucceeded, TemplateState.Destroyed); - //TODO: this should not be needed, but it happened during testing where multiple success event is sent to callback + // TODO: this should not be needed, but it happened during testing where + // multiple success event is sent to callback stateMachine.addTransition(TemplateState.Ready, TemplateEvent.OperationSucceeded, TemplateState.Ready); } 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 43c02f6b6c2..73c960fef9e 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 @@ -40,16 +40,12 @@ import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.storage.DataStoreRole; 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); + private static final Logger s_logger = Logger.getLogger(ImageStoreProviderManagerImpl.class); @Inject ImageStoreDao dataStoreDao; @Inject @@ -67,10 +63,9 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager public ImageStoreEntity getImageStore(long dataStoreId) { ImageStoreVO dataStore = dataStoreDao.findById(dataStoreId); String providerName = dataStore.getProviderName(); - ImageStoreProvider provider = (ImageStoreProvider)providerManager.getDataStoreProvider(providerName); - ImageStoreEntity imgStore = ImageStoreImpl.getDataStore(dataStore, - driverMaps.get(provider.getName()), provider - ); + ImageStoreProvider provider = (ImageStoreProvider) providerManager.getDataStoreProvider(providerName); + ImageStoreEntity imgStore = ImageStoreImpl + .getDataStore(dataStore, driverMaps.get(provider.getName()), provider); // TODO Auto-generated method stub return imgStore; } @@ -120,8 +115,6 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager return imageStores; } - - @Override public List listImageCacheStores(Scope scope) { if (scope.getScopeType() != ScopeType.ZONE) { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index 95c952e1cd2..c6840d7aa17 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -44,11 +44,9 @@ import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.DataStoreRole; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; -import com.cloud.utils.storage.encoding.EncodingType; - public class ImageStoreImpl implements ImageStoreEntity { - private static final Logger s_logger = Logger.getLogger(ImageStoreImpl.class); + private static final Logger s_logger = Logger.getLogger(ImageStoreImpl.class); @Inject VMTemplateDao imageDao; @Inject @@ -59,7 +57,7 @@ public class ImageStoreImpl implements ImageStoreEntity { boolean needDownloadToCacheStorage = false; public ImageStoreImpl() { - + super(); } protected void configure(ImageStoreVO dataStoreVO, ImageStoreDriver imageDataStoreDriver, @@ -71,7 +69,7 @@ public class ImageStoreImpl implements ImageStoreEntity { public static ImageStoreEntity getDataStore(ImageStoreVO dataStoreVO, ImageStoreDriver imageDataStoreDriver, ImageStoreProvider provider) { - ImageStoreImpl instance = (ImageStoreImpl)ComponentContext.inject(ImageStoreImpl.class); + ImageStoreImpl instance = ComponentContext.inject(ImageStoreImpl.class); instance.configure(dataStoreVO, imageDataStoreDriver, provider); return instance; } @@ -90,8 +88,9 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public DataStoreRole getRole() { - return this.imageDataStoreVO.getRole(); + return this.imageDataStoreVO.getRole(); } + @Override public long getId() { // TODO Auto-generated method stub @@ -128,8 +127,7 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public boolean exists(DataObject object) { - return (objectInStoreMgr.findObject(object, - this) != null) ? true : false; + return (objectInStoreMgr.findObject(object, this) != null) ? true : false; } @Override @@ -137,11 +135,10 @@ public class ImageStoreImpl implements ImageStoreEntity { return this.imageDataStoreVO.getUuid(); } - public Date getCreated(){ + public Date getCreated() { return this.imageDataStoreVO.getCreated(); } - @Override public DataObject create(DataObject obj) { DataObject object = objectInStoreMgr.create(obj, this); @@ -150,18 +147,18 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public boolean delete(DataObject obj) { - AsyncCallFuture future = new AsyncCallFuture(); - this.driver.deleteAsync(obj, future); - try { - future.get(); - } catch (InterruptedException e) { - s_logger.debug("failed delete obj", e); - return false; - } catch (ExecutionException e) { - s_logger.debug("failed delete obj", e); - return false; - } - objectInStoreMgr.delete(obj); + AsyncCallFuture future = new AsyncCallFuture(); + this.driver.deleteAsync(obj, future); + try { + future.get(); + } catch (InterruptedException e) { + s_logger.debug("failed delete obj", e); + return false; + } catch (ExecutionException e) { + s_logger.debug("failed delete obj", e); + return false; + } + objectInStoreMgr.delete(obj); return true; } @@ -175,7 +172,6 @@ public class ImageStoreImpl implements ImageStoreEntity { return imageDataStoreVO.getDataCenterId(); } - @Override public String getProviderName() { return imageDataStoreVO.getProviderName(); @@ -186,15 +182,13 @@ public class ImageStoreImpl implements ImageStoreEntity { return imageDataStoreVO.getProtocol(); } - - @Override public DataStoreTO getTO() { return getDriver().getStoreTO(this); } @Override - public String getMountPoint(){ + public String getMountPoint() { return this.imageDataStoreVO.getParent(); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index b17fc3df254..e4be6277eac 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -54,8 +54,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; public class TemplateObject implements TemplateInfo { - private static final Logger s_logger = Logger - .getLogger(TemplateObject.class); + private static final Logger s_logger = Logger.getLogger(TemplateObject.class); private VMTemplateVO imageVO; private DataStore dataStore; @Inject @@ -64,8 +63,10 @@ public class TemplateObject implements TemplateInfo { VMTemplateDao imageDao; @Inject ObjectInDataStoreManager objectInStoreMgr; - @Inject VMTemplatePoolDao templatePoolDao; - @Inject TemplateDataStoreDao templateStoreDao; + @Inject + VMTemplatePoolDao templatePoolDao; + @Inject + TemplateDataStoreDao templateStoreDao; public TemplateObject() { } @@ -81,7 +82,6 @@ public class TemplateObject implements TemplateInfo { return to; } - public void setSize(Long size) { this.imageVO.setSize(size); } @@ -114,7 +114,7 @@ public class TemplateObject implements TemplateInfo { public String getUri() { VMTemplateVO image = imageDao.findById(this.imageVO.getId()); - return image.getUrl(); + return image.getUrl(); } @@ -125,28 +125,21 @@ public class TemplateObject implements TemplateInfo { } /* - -// If the template that was passed into this allocator is not installed in the storage pool, - // add 3 * (template size on secondary storage) to the running total - VMTemplateHostVO templateHostVO = _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), null); - - if (templateHostVO == null) { - VMTemplateSwiftVO templateSwiftVO = _swiftMgr.findByTmpltId(templateForVmCreation.getId()); - if (templateSwiftVO != null) { - long templateSize = templateSwiftVO.getPhysicalSize(); - if (templateSize == 0) { - templateSize = templateSwiftVO.getSize(); - } - totalAllocatedSize += (templateSize + _extraBytesPerVolume); - } - } else { - long templateSize = templateHostVO.getPhysicalSize(); - if ( templateSize == 0 ){ - templateSize = templateHostVO.getSize(); - } - totalAllocatedSize += (templateSize + _extraBytesPerVolume); - } - + * + * // If the template that was passed into this allocator is not + * installed in the storage pool, // add 3 * (template size on secondary + * storage) to the running total VMTemplateHostVO templateHostVO = + * _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), null); + * + * if (templateHostVO == null) { VMTemplateSwiftVO templateSwiftVO = + * _swiftMgr.findByTmpltId(templateForVmCreation.getId()); if + * (templateSwiftVO != null) { long templateSize = + * templateSwiftVO.getPhysicalSize(); if (templateSize == 0) { + * templateSize = templateSwiftVO.getSize(); } totalAllocatedSize += + * (templateSize + _extraBytesPerVolume); } } else { long templateSize = + * templateHostVO.getPhysicalSize(); if ( templateSize == 0 ){ + * templateSize = templateHostVO.getSize(); } totalAllocatedSize += + * (templateSize + _extraBytesPerVolume); } */ VMTemplateVO image = imageDao.findById(this.imageVO.getId()); return image.getSize(); @@ -164,8 +157,7 @@ public class TemplateObject implements TemplateInfo { public boolean stateTransit(TemplateEvent e) throws NoTransitionException { this.imageVO = imageDao.findById(this.imageVO.getId()); - boolean result= imageMgr.getStateMachine().transitTo(this.imageVO, e, null, - imageDao); + boolean result = imageMgr.getStateMachine().transitTo(this.imageVO, e, null, imageDao); this.imageVO = imageDao.findById(this.imageVO.getId()); return result; } @@ -173,12 +165,12 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(Event event) { try { - if (this.getDataStore().getRole() == DataStoreRole.Image || - this.getDataStore().getRole() == DataStoreRole.ImageCache) { + if (this.getDataStore().getRole() == DataStoreRole.Image + || this.getDataStore().getRole() == DataStoreRole.ImageCache) { TemplateEvent templEvent = null; if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { templEvent = TemplateEvent.CreateRequested; - } else if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested){ + } else if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) { templEvent = TemplateEvent.DestroyRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { templEvent = TemplateEvent.OperationSucceeded; @@ -195,9 +187,9 @@ public class TemplateObject implements TemplateInfo { } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); - } finally{ + } finally { // in case of OperationFailed, expunge the entry - if ( event == ObjectInDataStoreStateMachine.Event.OperationFailed){ + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { objectInStoreMgr.delete(this); } } @@ -206,63 +198,64 @@ public class TemplateObject implements TemplateInfo { @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { - if (this.getDataStore().getRole() == DataStoreRole.Primary) { - if (answer instanceof CopyCmdAnswer) { - CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; - TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData(); - VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore().getId(), this.getId()); - templatePoolRef.setDownloadPercent(100); - templatePoolRef.setDownloadState(Status.DOWNLOADED); - templatePoolRef.setLocalDownloadPath(newTemplate.getPath()); - templatePoolRef.setInstallPath(newTemplate.getPath()); - templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); - } - } else if (this.getDataStore().getRole() == DataStoreRole.Image || - this.getDataStore().getRole() == DataStoreRole.ImageCache) { - if (answer instanceof CopyCmdAnswer) { - CopyCmdAnswer cpyAnswer = (CopyCmdAnswer)answer; - TemplateObjectTO newTemplate = (TemplateObjectTO)cpyAnswer.getNewData(); - TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this.getDataStore().getId(), - this.getId()); - templateStoreRef.setInstallPath(newTemplate.getPath()); - templateStoreRef.setDownloadPercent(100); - templateStoreRef.setDownloadState(Status.DOWNLOADED); - templateStoreRef.setSize(newTemplate.getSize()); - templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); + if (this.getDataStore().getRole() == DataStoreRole.Primary) { + if (answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer; + TemplateObjectTO newTemplate = (TemplateObjectTO) cpyAnswer.getNewData(); + VMTemplateStoragePoolVO templatePoolRef = templatePoolDao.findByPoolTemplate(this.getDataStore() + .getId(), this.getId()); + templatePoolRef.setDownloadPercent(100); + templatePoolRef.setDownloadState(Status.DOWNLOADED); + templatePoolRef.setLocalDownloadPath(newTemplate.getPath()); + templatePoolRef.setInstallPath(newTemplate.getPath()); + templatePoolDao.update(templatePoolRef.getId(), templatePoolRef); + } + } else if (this.getDataStore().getRole() == DataStoreRole.Image + || this.getDataStore().getRole() == DataStoreRole.ImageCache) { + if (answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer; + TemplateObjectTO newTemplate = (TemplateObjectTO) cpyAnswer.getNewData(); + TemplateDataStoreVO templateStoreRef = this.templateStoreDao.findByStoreTemplate(this + .getDataStore().getId(), this.getId()); + templateStoreRef.setInstallPath(newTemplate.getPath()); + templateStoreRef.setDownloadPercent(100); + templateStoreRef.setDownloadState(Status.DOWNLOADED); + templateStoreRef.setSize(newTemplate.getSize()); + templateStoreDao.update(templateStoreRef.getId(), templateStoreRef); if (this.getDataStore().getRole() == DataStoreRole.Image) { VMTemplateVO templateVO = this.imageDao.findById(this.getId()); templateVO.setFormat(newTemplate.getFormat()); templateVO.setSize(newTemplate.getSize()); this.imageDao.update(templateVO.getId(), templateVO); } - } + } - TemplateEvent templEvent = null; - if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { - templEvent = TemplateEvent.CreateRequested; - } else if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested){ + TemplateEvent templEvent = null; + if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { + templEvent = TemplateEvent.CreateRequested; + } else if (event == ObjectInDataStoreStateMachine.Event.DestroyRequested) { templEvent = TemplateEvent.DestroyRequested; } else if (event == ObjectInDataStoreStateMachine.Event.OperationSuccessed) { - templEvent = TemplateEvent.OperationSucceeded; - } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - templEvent = TemplateEvent.OperationFailed; - } + templEvent = TemplateEvent.OperationSucceeded; + } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + templEvent = TemplateEvent.OperationFailed; + } - if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { - this.stateTransit(templEvent); - } - } + if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { + this.stateTransit(templEvent); + } + } objectInStoreMgr.update(this, event); } catch (NoTransitionException e) { s_logger.debug("failed to update state", e); throw new CloudRuntimeException("Failed to update state" + e.toString()); - } catch (Exception ex){ + } catch (Exception ex) { s_logger.debug("failed to process event and answer", ex); objectInStoreMgr.delete(this); throw new CloudRuntimeException("Failed to process event", ex); - } finally{ + } finally { // in case of OperationFailed, expunge the entry - if ( event == ObjectInDataStoreStateMachine.Event.OperationFailed){ + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { objectInStoreMgr.delete(this); } } @@ -270,26 +263,26 @@ public class TemplateObject implements TemplateInfo { @Override public DataTO getTO() { - DataTO to = null; - if (this.dataStore == null) { - to = new TemplateObjectTO(this); - } else { - to = this.dataStore.getDriver().getTO(this); - if (to == null) { - to = new TemplateObjectTO(this); - } - } + DataTO to = null; + if (this.dataStore == null) { + to = new TemplateObjectTO(this); + } else { + to = this.dataStore.getDriver().getTO(this); + if (to == null) { + to = new TemplateObjectTO(this); + } + } return to; } @Override public String getInstallPath() { - if (this.dataStore == null) { - return null; - } - DataObjectInStore obj = objectInStoreMgr.findObject(this, this.dataStore); - return obj.getInstallPath(); + if (this.dataStore == null) { + return null; + } + DataObjectInStore obj = objectInStoreMgr.findObject(this, this.dataStore); + return obj.getInstallPath(); } @Override diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java index 8e5b1640a06..4d932964a64 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/MockLocalNfsSecondaryStorageResource.java @@ -21,26 +21,21 @@ import static java.util.Arrays.asList; import java.io.InputStream; import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.util.HashMap; import java.util.List; import javax.naming.ConfigurationException; -import org.springframework.stereotype.Component; - -import com.amazonaws.services.s3.model.S3ObjectSummary; - import org.apache.cloudstack.storage.command.DownloadSystemTemplateCommand; import org.apache.cloudstack.storage.resource.NfsSecondaryStorageResource; import org.apache.cloudstack.storage.template.DownloadManagerImpl; +import org.springframework.stereotype.Component; +import com.amazonaws.services.s3.model.S3ObjectSummary; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.storage.ssCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.agent.api.to.S3TO; @@ -54,10 +49,9 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; @Component -public class MockLocalNfsSecondaryStorageResource extends - NfsSecondaryStorageResource { +public class MockLocalNfsSecondaryStorageResource extends NfsSecondaryStorageResource { - public MockLocalNfsSecondaryStorageResource(){ + public MockLocalNfsSecondaryStorageResource() { _dlMgr = new DownloadManagerImpl(); _storage = new JavaStorageLayer(); HashMap params = new HashMap(); @@ -68,37 +62,32 @@ public class MockLocalNfsSecondaryStorageResource extends // TODO Auto-generated catch block e.printStackTrace(); } - - createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh"); - /* - _storage = new JavaStorageLayer(); - ((DownloadManagerImpl)_dlMgr).setThreadPool(Executors.newFixedThreadPool(10)); - ((DownloadManagerImpl)_dlMgr).setStorageLayer(_storage); - */ + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), + "create_privatetemplate_from_snapshot_xen.sh"); } @Override - public String getRootDir(String secUrl){ + public String getRootDir(String secUrl) { return "/mnt"; } @Override public Answer executeRequest(Command cmd) { - if (cmd instanceof DownloadSystemTemplateCommand){ - return execute((DownloadSystemTemplateCommand)cmd); + if (cmd instanceof DownloadSystemTemplateCommand) { + return execute((DownloadSystemTemplateCommand) cmd); } else { - //return Answer.createUnsupportedCommandAnswer(cmd); + // return Answer.createUnsupportedCommandAnswer(cmd); return super.executeRequest(cmd); } } - private Answer execute(DownloadSystemTemplateCommand cmd){ + private Answer execute(DownloadSystemTemplateCommand cmd) { DataStoreTO dstore = cmd.getDataStore(); - if ( dstore instanceof S3TO ){ - //TODO: how to handle download progress for S3 - S3TO s3 = (S3TO)cmd.getDataStore(); + if (dstore instanceof S3TO) { + // TODO: how to handle download progress for S3 + S3TO s3 = (S3TO) cmd.getDataStore(); String url = cmd.getUrl(); String user = null; String password = null; @@ -108,19 +97,16 @@ public class MockLocalNfsSecondaryStorageResource extends } // get input stream from the given url InputStream in = UriUtils.getInputStreamFromUrl(url, user, password); - URI uri; URL urlObj; try { - uri = new URI(url); urlObj = new URL(url); - } catch (URISyntaxException e) { - throw new CloudRuntimeException("URI is incorrect: " + url); } catch (MalformedURLException e) { throw new CloudRuntimeException("URL is incorrect: " + url); } final String bucket = s3.getBucketName(); - // convention is no / in the end for install path based on S3Utils implementation. + // convention is no / in the end for install path based on S3Utils + // implementation. String path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); // template key is // TEMPLATE_ROOT_DIR/account_id/template_id/template_name @@ -130,19 +116,19 @@ public class MockLocalNfsSecondaryStorageResource extends if (s3Obj == null || s3Obj.size() == 0) { return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key); } else { - return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj.get(0) - .getETag()); + return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj + .get(0).getSize(), s3Obj.get(0).getETag()); } - } - else if ( dstore instanceof NfsTO ){ + } else if (dstore instanceof NfsTO) { return new Answer(cmd, false, "Nfs needs to be pre-installed with system vm templates"); - } - else if ( dstore instanceof SwiftTO ){ - //TODO: need to move code from execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, but we need to handle - // source is url, most likely we need to modify our existing swiftUpload python script. + } else if (dstore instanceof SwiftTO) { + // TODO: need to move code from + // execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, + // but we need to handle + // source is url, most likely we need to modify our existing + // swiftUpload python script. return new Answer(cmd, false, "Swift is not currently support DownloadCommand"); - } - else{ + } else { return new Answer(cmd, false, "Unsupported image data store: " + dstore); } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java index b369459a9a8..3d300de1060 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java @@ -16,8 +16,6 @@ // under the License. package org.apache.cloudstack.storage.allocator; -import static org.junit.Assert.fail; - import java.util.ArrayList; import java.util.List; import java.util.UUID; @@ -36,6 +34,7 @@ import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -70,370 +69,372 @@ import com.cloud.vm.VirtualMachineProfile; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:/storageContext.xml") public class StorageAllocatorTest { - @Inject - PrimaryDataStoreDao storagePoolDao; - @Inject - StorageManager storageMgr; - @Inject - DiskOfferingDao diskOfferingDao; - @Inject - VolumeDao volumeDao; - @Inject - HostPodDao podDao; - @Inject - ClusterDao clusterDao; - @Inject - DataCenterDao dcDao; - @Inject - StoragePoolDetailsDao poolDetailsDao; - @Inject - DataStoreProviderManager providerMgr; - Long dcId = 1l; - Long podId = 1l; - Long clusterId = 1l; - Long volumeId = null; - Long diskOfferingId = null; - Long storagePoolId = null; - VolumeVO volume = null; - DiskOfferingVO diskOffering = null; - StoragePoolVO storage = null; + @Inject + PrimaryDataStoreDao storagePoolDao; + @Inject + StorageManager storageMgr; + @Inject + DiskOfferingDao diskOfferingDao; + @Inject + VolumeDao volumeDao; + @Inject + HostPodDao podDao; + @Inject + ClusterDao clusterDao; + @Inject + DataCenterDao dcDao; + @Inject + StoragePoolDetailsDao poolDetailsDao; + @Inject + DataStoreProviderManager providerMgr; + Long dcId = 1l; + Long podId = 1l; + Long clusterId = 1l; + Long volumeId = null; + Long diskOfferingId = null; + Long storagePoolId = null; + VolumeVO volume = null; + DiskOfferingVO diskOffering = null; + StoragePoolVO storage = null; - @Before - public void setup() throws Exception { - ComponentContext.initComponentsLifeCycle(); + @Before + public void setup() throws Exception { + ComponentContext.initComponentsLifeCycle(); - } + } - protected void createDb() { - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); - dc = dcDao.persist(dc); - dcId = dc.getId(); + protected void createDb() { + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "255.255.255.255", "", 8, "test"); - pod = podDao.persist(pod); - podId = pod.getId(); - - ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); - cluster.setHypervisorType(HypervisorType.XenServer.toString()); - cluster.setClusterType(ClusterType.CloudManaged); - cluster.setManagedState(ManagedState.Managed); - cluster = clusterDao.persist(cluster); - clusterId = cluster.getId(); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "255.255.255.255", "", 8, "test"); + pod = podDao.persist(pod); + podId = pod.getId(); - DataStoreProvider provider = providerMgr.getDataStoreProvider("cloudstack primary data store provider"); - storage = new StoragePoolVO(); - storage.setDataCenterId(dcId); - storage.setPodId(podId); - storage.setPoolType(StoragePoolType.NetworkFilesystem); - storage.setClusterId(clusterId); - storage.setStatus(StoragePoolStatus.Up); - storage.setScope(ScopeType.CLUSTER); - storage.setAvailableBytes(1000); - storage.setCapacityBytes(20000); - storage.setHostAddress(UUID.randomUUID().toString()); - storage.setPath(UUID.randomUUID().toString()); - storage.setStorageProviderName(provider.getName()); - storage = storagePoolDao.persist(storage); - storagePoolId = storage.getId(); + ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); + cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setClusterType(ClusterType.CloudManaged); + cluster.setManagedState(ManagedState.Managed); + cluster = clusterDao.persist(cluster); + clusterId = cluster.getId(); - storageMgr.createCapacityEntry(storage.getId()); + DataStoreProvider provider = providerMgr.getDataStoreProvider("cloudstack primary data store provider"); + storage = new StoragePoolVO(); + storage.setDataCenterId(dcId); + storage.setPodId(podId); + storage.setPoolType(StoragePoolType.NetworkFilesystem); + storage.setClusterId(clusterId); + storage.setStatus(StoragePoolStatus.Up); + storage.setScope(ScopeType.CLUSTER); + storage.setAvailableBytes(1000); + storage.setCapacityBytes(20000); + storage.setHostAddress(UUID.randomUUID().toString()); + storage.setPath(UUID.randomUUID().toString()); + storage.setStorageProviderName(provider.getName()); + storage = storagePoolDao.persist(storage); + storagePoolId = storage.getId(); - diskOffering = new DiskOfferingVO(); - diskOffering.setDiskSize(500); - diskOffering.setName("test-disk"); - diskOffering.setSystemUse(false); - diskOffering.setUseLocalStorage(false); - diskOffering.setCustomized(false); - diskOffering.setRecreatable(false); - diskOffering = diskOfferingDao.persist(diskOffering); - diskOfferingId = diskOffering.getId(); + storageMgr.createCapacityEntry(storage.getId()); - volume = new VolumeVO(Volume.Type.ROOT, "volume", dcId, 1, 1, diskOffering.getId(), diskOffering.getDiskSize()); - volume = volumeDao.persist(volume); - volumeId = volume.getId(); - } - - - - @Inject - List allocators; - @Test - public void testClusterAllocatorMultiplePools() { - Long newStorageId = null; - try { - createDb(); - - DataStoreProvider provider = providerMgr.getDataStoreProvider("cloudstack primary data store provider"); - storage = new StoragePoolVO(); - storage.setDataCenterId(dcId); - storage.setPodId(podId); - storage.setPoolType(StoragePoolType.NetworkFilesystem); - storage.setClusterId(clusterId); - storage.setStatus(StoragePoolStatus.Up); - storage.setScope(ScopeType.CLUSTER); - storage.setAvailableBytes(1000); - storage.setCapacityBytes(20000); - storage.setHostAddress(UUID.randomUUID().toString()); - storage.setPath(UUID.randomUUID().toString()); - storage.setStorageProviderName(provider.getName()); - StoragePoolVO newStorage = storagePoolDao.persist(storage); - newStorageId = newStorage.getId(); - - DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - Assert.assertEquals(pools.size(), 1); - foundAcct++; - } - } + diskOffering = new DiskOfferingVO(); + diskOffering.setDiskSize(500); + diskOffering.setName("test-disk"); + diskOffering.setSystemUse(false); + diskOffering.setUseLocalStorage(false); + diskOffering.setCustomized(false); + diskOffering.setRecreatable(false); + diskOffering = diskOfferingDao.persist(diskOffering); + diskOfferingId = diskOffering.getId(); - if (foundAcct > 1 || foundAcct == 0) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - - if (newStorageId != null) { - storagePoolDao.remove(newStorageId); - } - Assert.fail(); - } - } - - @Test - public void testClusterAllocator() { - try { - createDb(); - DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - Assert.assertEquals(pools.get(0).getId(), storage.getId()); - foundAcct++; - } - } + volume = new VolumeVO(Volume.Type.ROOT, "volume", dcId, 1, 1, diskOffering.getId(), diskOffering.getDiskSize()); + volume = volumeDao.persist(volume); + volumeId = volume.getId(); + } - if (foundAcct > 1 || foundAcct == 0) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - Assert.fail(); - } - } - - - @Test - public void testClusterAllocatorWithTags() { - try { - createDb(); - StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true"); - poolDetailsDao.persist(detailVO); - DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId()); - List tags = new ArrayList(); - tags.add("high"); - diskOff.setTagsArray(tags); - diskOfferingDao.update(diskOff.getId(), diskOff); - - DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - Assert.assertEquals(pools.get(0).getId(), storage.getId()); - foundAcct++; - } - } + @Inject + List allocators; - if (foundAcct > 1 || foundAcct == 0) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - Assert.fail(); - } - } - - @Test - public void testClusterAllocatorWithWrongTag() { - try { - createDb(); - StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true"); - poolDetailsDao.persist(detailVO); - DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId()); - List tags = new ArrayList(); - tags.add("low"); - diskOff.setTagsArray(tags); - diskOfferingDao.update(diskOff.getId(), diskOff); - - DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - foundAcct++; - } - } + @Test + public void testClusterAllocatorMultiplePools() { + Long newStorageId = null; + try { + createDb(); - if (foundAcct != 0) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - Assert.fail(); - } - } - - @Test - public void testZoneWideStorageAllocator() { - try { - createDb(); - - StoragePoolVO pool = storagePoolDao.findById(storagePoolId); - pool.setScope(ScopeType.ZONE); - storagePoolDao.update(pool.getId(), pool); - - DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - Assert.assertEquals(pools.get(0).getId(), storage.getId()); - foundAcct++; - } - } + DataStoreProvider provider = providerMgr.getDataStoreProvider("cloudstack primary data store provider"); + storage = new StoragePoolVO(); + storage.setDataCenterId(dcId); + storage.setPodId(podId); + storage.setPoolType(StoragePoolType.NetworkFilesystem); + storage.setClusterId(clusterId); + storage.setStatus(StoragePoolStatus.Up); + storage.setScope(ScopeType.CLUSTER); + storage.setAvailableBytes(1000); + storage.setCapacityBytes(20000); + storage.setHostAddress(UUID.randomUUID().toString()); + storage.setPath(UUID.randomUUID().toString()); + storage.setStorageProviderName(provider.getName()); + StoragePoolVO newStorage = storagePoolDao.persist(storage); + newStorageId = newStorage.getId(); - if (foundAcct > 1 || foundAcct == 0) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - Assert.fail(); - } - } - - @Test - public void testPoolStateIsNotUp() { - try { - createDb(); - - StoragePoolVO pool = storagePoolDao.findById(storagePoolId); - pool.setScope(ScopeType.ZONE); - pool.setStatus(StoragePoolStatus.Maintenance); - storagePoolDao.update(pool.getId(), pool); - - DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - Assert.assertEquals(pools.get(0).getId(), storage.getId()); - foundAcct++; - } - } + DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + Assert.assertEquals(pools.size(), 1); + foundAcct++; + } + } - if (foundAcct == 1) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - Assert.fail(); - } - } - - - - - @Test - public void testLocalStorageAllocator() { - try { - createDb(); - - StoragePoolVO pool = storagePoolDao.findById(storagePoolId); - pool.setScope(ScopeType.HOST); - storagePoolDao.update(pool.getId(), pool); - - DiskOfferingVO diskOff = diskOfferingDao.findById(diskOfferingId); - diskOff.setUseLocalStorage(true); - diskOfferingDao.update(diskOfferingId, diskOff); - - DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer); - VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); - Mockito.when(storageMgr.storagePoolHasEnoughSpace( - Mockito.anyListOf(Volume.class), Mockito.any(StoragePool.class))).thenReturn(true); - DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); - int foundAcct = 0; - for (StoragePoolAllocator allocator : allocators) { - List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); - if (!pools.isEmpty()) { - Assert.assertEquals(pools.get(0).getId(), storage.getId()); - foundAcct++; - } - } + if (foundAcct > 1 || foundAcct == 0) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); - if (foundAcct > 1 || foundAcct == 0) { - Assert.fail(); - } - } catch (Exception e) { - cleanDb(); - Assert.fail(); - } - } - - protected void cleanDb() { - if (volumeId != null) { - volumeDao.remove(volumeId); - volumeId = null; - } - if (diskOfferingId != null) { - diskOfferingDao.remove(diskOfferingId); - diskOfferingId = null; - } - if (storagePoolId != null) { - storagePoolDao.remove(storagePoolId); - storagePoolId = null; - } - if (clusterId != null) { - clusterDao.remove(clusterId); - clusterId = null; - } - if (podId != null) { - podDao.remove(podId); - podId = null; - } - if (dcId != null) { - dcDao.remove(dcId); - dcId = null; - } - } + if (newStorageId != null) { + storagePoolDao.remove(newStorageId); + } + Assert.fail(); + } + } + + @Test + public void testClusterAllocator() { + try { + createDb(); + DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + Assert.assertEquals(pools.get(0).getId(), storage.getId()); + foundAcct++; + } + } + + if (foundAcct > 1 || foundAcct == 0) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); + Assert.fail(); + } + } + + @Test + public void testClusterAllocatorWithTags() { + try { + createDb(); + StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true"); + poolDetailsDao.persist(detailVO); + DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId()); + List tags = new ArrayList(); + tags.add("high"); + diskOff.setTagsArray(tags); + diskOfferingDao.update(diskOff.getId(), diskOff); + + DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + Assert.assertEquals(pools.get(0).getId(), storage.getId()); + foundAcct++; + } + } + + if (foundAcct > 1 || foundAcct == 0) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); + Assert.fail(); + } + } + + @Test + public void testClusterAllocatorWithWrongTag() { + try { + createDb(); + StoragePoolDetailVO detailVO = new StoragePoolDetailVO(this.storagePoolId, "high", "true"); + poolDetailsDao.persist(detailVO); + DiskOfferingVO diskOff = this.diskOfferingDao.findById(diskOffering.getId()); + List tags = new ArrayList(); + tags.add("low"); + diskOff.setTagsArray(tags); + diskOfferingDao.update(diskOff.getId(), diskOff); + + DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + foundAcct++; + } + } + + if (foundAcct != 0) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); + Assert.fail(); + } + } + + @Test + public void testZoneWideStorageAllocator() { + try { + createDb(); + + StoragePoolVO pool = storagePoolDao.findById(storagePoolId); + pool.setScope(ScopeType.ZONE); + storagePoolDao.update(pool.getId(), pool); + + DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.KVM); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when(vmProfile.getHypervisorType()).thenReturn(HypervisorType.KVM); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + Assert.assertEquals(pools.get(0).getId(), storage.getId()); + foundAcct++; + } + } + + if (foundAcct > 1 || foundAcct == 0) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); + Assert.fail(); + } + } + + @Test + public void testPoolStateIsNotUp() { + try { + createDb(); + + StoragePoolVO pool = storagePoolDao.findById(storagePoolId); + pool.setScope(ScopeType.ZONE); + pool.setStatus(StoragePoolStatus.Maintenance); + storagePoolDao.update(pool.getId(), pool); + + DiskProfile profile = new DiskProfile(volume, diskOffering, HypervisorType.XenServer); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + Assert.assertEquals(pools.get(0).getId(), storage.getId()); + foundAcct++; + } + } + + if (foundAcct == 1) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); + Assert.fail(); + } + } + + @Test + public void testLocalStorageAllocator() { + try { + createDb(); + + StoragePoolVO pool = storagePoolDao.findById(storagePoolId); + pool.setScope(ScopeType.HOST); + storagePoolDao.update(pool.getId(), pool); + + DiskOfferingVO diskOff = diskOfferingDao.findById(diskOfferingId); + diskOff.setUseLocalStorage(true); + diskOfferingDao.update(diskOfferingId, diskOff); + + DiskProfile profile = new DiskProfile(volume, diskOff, HypervisorType.XenServer); + VirtualMachineProfile vmProfile = Mockito.mock(VirtualMachineProfile.class); + Mockito.when( + storageMgr.storagePoolHasEnoughSpace(Matchers.anyListOf(Volume.class), + Matchers.any(StoragePool.class))).thenReturn(true); + DeploymentPlan plan = new DataCenterDeployment(dcId, podId, clusterId, null, null, null); + int foundAcct = 0; + for (StoragePoolAllocator allocator : allocators) { + List pools = allocator.allocateToPool(profile, vmProfile, plan, new ExcludeList(), 1); + if (!pools.isEmpty()) { + Assert.assertEquals(pools.get(0).getId(), storage.getId()); + foundAcct++; + } + } + + if (foundAcct > 1 || foundAcct == 0) { + Assert.fail(); + } + } catch (Exception e) { + cleanDb(); + Assert.fail(); + } + } + + protected void cleanDb() { + if (volumeId != null) { + volumeDao.remove(volumeId); + volumeId = null; + } + if (diskOfferingId != null) { + diskOfferingDao.remove(diskOfferingId); + diskOfferingId = null; + } + if (storagePoolId != null) { + storagePoolDao.remove(storagePoolId); + storagePoolId = null; + } + if (clusterId != null) { + clusterDao.remove(clusterId); + clusterId = null; + } + if (podId != null) { + podDao.remove(podId); + podId = null; + } + if (dcId != null) { + dcDao.remove(dcId); + dcId = null; + } + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java index 4790086b2e1..e3172176f9a 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTestConfiguration.java @@ -39,35 +39,28 @@ import com.cloud.storage.dao.StoragePoolDetailsDaoImpl; import com.cloud.storage.dao.VMTemplateDaoImpl; import com.cloud.vm.UserVmManager; - @Configuration -@ComponentScan(basePackageClasses={ - StoragePoolDetailsDaoImpl.class, - PrimaryDataStoreDaoImpl.class, - VMTemplateDaoImpl.class, - HostDaoImpl.class, - DomainDaoImpl.class, - DataCenterDaoImpl.class}, - includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)}, - useDefaultFilters=false - ) +@ComponentScan(basePackageClasses = { StoragePoolDetailsDaoImpl.class, PrimaryDataStoreDaoImpl.class, + VMTemplateDaoImpl.class, HostDaoImpl.class, DomainDaoImpl.class, DataCenterDaoImpl.class }, + includeFilters = { @Filter(value = Library.class, type = FilterType.CUSTOM) }, useDefaultFilters = false) public class StorageAllocatorTestConfiguration { - @Bean - public UserVmManager UserVmManager() { - return Mockito.mock(UserVmManager.class); - } - @Bean - public StorageManager StorageManager() { - return Mockito.mock(StorageManager.class); - } + @Bean + public UserVmManager UserVmManager() { + return Mockito.mock(UserVmManager.class); + } - public static class Library implements TypeFilter { + @Bean + public StorageManager StorageManager() { + return Mockito.mock(StorageManager.class); + } - @Override - public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { - mdr.getClassMetadata().getClassName(); - ComponentScan cs = StorageAllocatorTestConfiguration.class.getAnnotation(ComponentScan.class); - return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); - } - } + public static class Library implements TypeFilter { + + @Override + public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException { + mdr.getClassMetadata().getClassName(); + ComponentScan cs = StorageAllocatorTestConfiguration.class.getAnnotation(ComponentScan.class); + return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs); + } + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTest.java index bde5804e624..3fee7ac3bea 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTest.java @@ -23,7 +23,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; -@Target({TYPE, METHOD}) +@Target({ TYPE, METHOD }) @Retention(RUNTIME) public @interface AopTest { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java index 63669c453d7..902f5953eb1 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/AopTestAdvice.java @@ -21,14 +21,14 @@ import org.aspectj.lang.ProceedingJoinPoint; import com.cloud.utils.db.Transaction; public class AopTestAdvice { - public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { - Transaction txn = Transaction.open(call.getSignature().getName()); - Object ret = null; - try { - ret = call.proceed(); - } finally { - txn.close(); - } - return ret; - } + public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { + Transaction txn = Transaction.open(call.getSignature().getName()); + Object ret = null; + try { + ret = call.proceed(); + } finally { + txn.close(); + } + return ret; + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index acb61069074..60f86d86ddb 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -22,11 +22,7 @@ import org.apache.cloudstack.acl.APIChecker; import org.apache.cloudstack.engine.service.api.OrchestrationService; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; import org.apache.cloudstack.framework.rpc.RpcProvider; -import org.apache.cloudstack.storage.HostEndpointRpcServer; import org.apache.cloudstack.storage.cache.manager.StorageCacheManagerImpl; -import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao; -import org.apache.cloudstack.storage.image.db.ImageStoreDaoImpl; -import org.apache.cloudstack.storage.image.db.ImageStoreDetailsDaoImpl; import org.apache.cloudstack.storage.test.ChildTestConfiguration.Library; import org.apache.cloudstack.test.utils.SpringUtils; import org.mockito.Mockito; @@ -79,7 +75,6 @@ import com.cloud.storage.dao.VMTemplatePoolDaoImpl; import com.cloud.storage.dao.VMTemplateZoneDaoImpl; import com.cloud.storage.dao.VolumeDaoImpl; import com.cloud.storage.dao.VolumeHostDaoImpl; -import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.download.DownloadMonitorImpl; import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; @@ -98,164 +93,138 @@ import com.cloud.vm.dao.NicDaoImpl; import com.cloud.vm.dao.SecondaryStorageVmDaoImpl; import com.cloud.vm.dao.UserVmDaoImpl; import com.cloud.vm.dao.UserVmDetailsDaoImpl; -import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDaoImpl; import com.cloud.vm.snapshot.dao.VMSnapshotDaoImpl; -@Configuration -@ComponentScan(basePackageClasses={ - NicDaoImpl.class, - VMInstanceDaoImpl.class, - VMTemplateHostDaoImpl.class, - VolumeHostDaoImpl.class, - VolumeDaoImpl.class, - VMTemplatePoolDaoImpl.class, - ResourceTagsDaoImpl.class, - VMTemplateDaoImpl.class, - MockStorageMotionStrategy.class, - ConfigurationDaoImpl.class, - ClusterDaoImpl.class, - HostPodDaoImpl.class, - VMTemplateZoneDaoImpl.class, - VMTemplateDetailsDaoImpl.class, - HostDetailsDaoImpl.class, - HostTagsDaoImpl.class, - HostTransferMapDaoImpl.class, - DataCenterIpAddressDaoImpl.class, - DataCenterLinkLocalIpAddressDaoImpl.class, - DataCenterVnetDaoImpl.class, - PodVlanDaoImpl.class, - DcDetailsDaoImpl.class, - DiskOfferingDaoImpl.class, - StoragePoolHostDaoImpl.class, - UserVmDaoImpl.class, - UserVmDetailsDaoImpl.class, - ServiceOfferingDaoImpl.class, - CapacityDaoImpl.class, - SnapshotDaoImpl.class, - VMSnapshotDaoImpl.class, - OCFS2ManagerImpl.class, - ClusterDetailsDaoImpl.class, - SecondaryStorageVmDaoImpl.class, - ConsoleProxyDaoImpl.class, - StoragePoolWorkDaoImpl.class, - StorageCacheManagerImpl.class, - UserDaoImpl.class, - DataCenterDaoImpl.class, - StoragePoolDetailsDaoImpl.class, - DomainDaoImpl.class, - DownloadMonitorImpl.class, - AccountDaoImpl.class -}, -includeFilters={@Filter(value=Library.class, type=FilterType.CUSTOM)}, -useDefaultFilters=false -) -public class ChildTestConfiguration extends TestConfiguration { - - @Bean - public SecondaryStorageVmManager secondaryStoreageMgr() { - return Mockito.mock(SecondaryStorageVmManager.class); - } - @Bean - public HostDao hostDao() { - return Mockito.spy(new HostDaoImpl()); - } - - @Bean - public EndPointSelector selector() { - return Mockito.mock(EndPointSelector.class); - } - @Bean - public AgentManager agentMgr() { - return new DirectAgentManagerSimpleImpl(); - } - +@Configuration +@ComponentScan(basePackageClasses = { NicDaoImpl.class, VMInstanceDaoImpl.class, VMTemplateHostDaoImpl.class, + VolumeHostDaoImpl.class, VolumeDaoImpl.class, VMTemplatePoolDaoImpl.class, ResourceTagsDaoImpl.class, + VMTemplateDaoImpl.class, MockStorageMotionStrategy.class, ConfigurationDaoImpl.class, ClusterDaoImpl.class, + HostPodDaoImpl.class, VMTemplateZoneDaoImpl.class, VMTemplateDetailsDaoImpl.class, HostDetailsDaoImpl.class, + HostTagsDaoImpl.class, HostTransferMapDaoImpl.class, DataCenterIpAddressDaoImpl.class, + DataCenterLinkLocalIpAddressDaoImpl.class, DataCenterVnetDaoImpl.class, PodVlanDaoImpl.class, + DcDetailsDaoImpl.class, DiskOfferingDaoImpl.class, StoragePoolHostDaoImpl.class, UserVmDaoImpl.class, + UserVmDetailsDaoImpl.class, ServiceOfferingDaoImpl.class, CapacityDaoImpl.class, SnapshotDaoImpl.class, + VMSnapshotDaoImpl.class, OCFS2ManagerImpl.class, ClusterDetailsDaoImpl.class, SecondaryStorageVmDaoImpl.class, + ConsoleProxyDaoImpl.class, StoragePoolWorkDaoImpl.class, StorageCacheManagerImpl.class, UserDaoImpl.class, + DataCenterDaoImpl.class, StoragePoolDetailsDaoImpl.class, DomainDaoImpl.class, DownloadMonitorImpl.class, + AccountDaoImpl.class }, includeFilters = { @Filter(value = Library.class, type = FilterType.CUSTOM) }, + useDefaultFilters = false) +public class ChildTestConfiguration extends TestConfiguration { + @Bean - public HostEndpointRpcServer rpcServer() { - return new MockHostEndpointRpcServerDirectCallResource(); + public SecondaryStorageVmManager secondaryStoreageMgr() { + return Mockito.mock(SecondaryStorageVmManager.class); } - + + @Bean + public HostDao hostDao() { + return Mockito.spy(new HostDaoImpl()); + } + + @Bean + public EndPointSelector selector() { + return Mockito.mock(EndPointSelector.class); + } + + @Bean + public AgentManager agentMgr() { + return new DirectAgentManagerSimpleImpl(); + } + @Bean public ResourceLimitService limtServe() { return Mockito.mock(ResourceLimitService.class); } - + @Bean public AccountManager acctMgt() { return Mockito.mock(AccountManager.class); } + @Bean public RpcProvider rpcProvider() { - return Mockito.mock(RpcProvider.class); + return Mockito.mock(RpcProvider.class); } + @Bean public ClusteredAgentRebalanceService _rebalanceService() { return Mockito.mock(ClusteredAgentRebalanceService.class); } + @Bean public UserAuthenticator authenticator() { return Mockito.mock(UserAuthenticator.class); } + @Bean public OrchestrationService orchSrvc() { return Mockito.mock(OrchestrationService.class); } + @Bean public APIChecker apiChecker() { return Mockito.mock(APIChecker.class); } + @Bean public TemplateManager templateMgr() { - return Mockito.mock(TemplateManager.class); + return Mockito.mock(TemplateManager.class); } - + @Bean public VolumeManager volumeMgr() { - return Mockito.mock(VolumeManager.class); + return Mockito.mock(VolumeManager.class); } + @Bean public SwiftManager switfMgr() { - return Mockito.mock(SwiftManager.class); + return Mockito.mock(SwiftManager.class); } + @Bean public ManagementServer server() { - return Mockito.mock(ManagementServer.class); + return Mockito.mock(ManagementServer.class); } + @Bean public VirtualMachineManager vmMgr() { - return Mockito.mock(VirtualMachineManager.class); + return Mockito.mock(VirtualMachineManager.class); } - + @Bean public S3Manager s3Mgr() { - return Mockito.mock(S3Manager.class); + return Mockito.mock(S3Manager.class); } + @Bean public SnapshotManager snapshotMgr() { return Mockito.mock(SnapshotManager.class); } - + @Bean public ResourceManager resourceMgr() { - return Mockito.mock(ResourceManager.class); + return Mockito.mock(ResourceManager.class); } + @Bean public DomainRouterDao domainRouterDao() { - return Mockito.mock(DomainRouterDao.class); + return Mockito.mock(DomainRouterDao.class); } + @Bean public StorageManager storageMgr() { - return Mockito.mock(StorageManager.class); + return Mockito.mock(StorageManager.class); } - + @Bean public AlertManager alertMgr() { return Mockito.mock(AlertManager.class); } - + @Bean public HypervisorGuruManager hypervisorGuruMgr() { - return Mockito.mock(HypervisorGuruManager.class); + return Mockito.mock(HypervisorGuruManager.class); } public static class Library implements TypeFilter { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java index 726ea010c66..26f4c5da0e9 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/CloudStackTestNGBase.java @@ -25,7 +25,6 @@ import org.testng.annotations.Parameters; import org.testng.annotations.Test; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { @@ -54,12 +53,12 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { } @BeforeMethod(alwaysRun = true) - protected void injectDB(Method testMethod) throws Exception { + protected void injectDB(Method testMethod) throws Exception { txn = Transaction.open(testMethod.getName()); } @Test - protected void injectMockitoTest() { + protected void injectMockitoTest() { injectMockito(); } @@ -71,17 +70,14 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { } @BeforeMethod(alwaysRun = true) - - @Parameters({"devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", - "devcloud-host-ip", "template-url", "devcloud-local-storage-uuid", - "primary-storage-want-to-add", "devcloud-secondary-storage", "s3-accesskey", "s3-secretkey", "s3-endpoint", - "s3-template-bucket", "s3-usehttps", "image-install-path", "primary-storage-uuid-want-to-add", "script-path", - "hypervisor"}) - protected void setup(String hostuuid, String gateway, String cidr, - String hostIp, String templateUrl, String localStorageUuid, - String primaryStorage, String secondaryStorage, String s3_accessKey, String s3_secretKey, String s3_endpoint, String s3_template_bucket, - String s3_usehttps, String imageInstallPath, String primaryStorageUuid, String scriptPath, - String hypervisor) { + @Parameters({ "devcloud-host-uuid", "devcloud-host-gateway", "devcloud-host-cidr", "devcloud-host-ip", + "template-url", "devcloud-local-storage-uuid", "primary-storage-want-to-add", "devcloud-secondary-storage", + "s3-accesskey", "s3-secretkey", "s3-endpoint", "s3-template-bucket", "s3-usehttps", "image-install-path", + "primary-storage-uuid-want-to-add", "script-path", "hypervisor" }) + protected void setup(String hostuuid, String gateway, String cidr, String hostIp, String templateUrl, + String localStorageUuid, String primaryStorage, String secondaryStorage, String s3_accessKey, + String s3_secretKey, String s3_endpoint, String s3_template_bucket, String s3_usehttps, + String imageInstallPath, String primaryStorageUuid, String scriptPath, String hypervisor) { this.hostGuid = hostuuid; this.hostGateway = gateway; this.hostCidr = cidr; @@ -133,14 +129,13 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { return this.primaryStorageUrl; } - public String getSecondaryStorage() { - return secondaryStorage; - } - - public void setSecondaryStorage(String secondaryStorage) { - this.secondaryStorage = secondaryStorage; - } + public String getSecondaryStorage() { + return secondaryStorage; + } + public void setSecondaryStorage(String secondaryStorage) { + this.secondaryStorage = secondaryStorage; + } public String getS3AccessKey() { return s3AccessKey; @@ -186,13 +181,12 @@ public class CloudStackTestNGBase extends AbstractTestNGSpringContextTests { this.scriptPath = scriptPath; } - public HypervisorType getHypervisor() { - return hypervisor; - } - - public void setHypervisor(HypervisorType hypervisor) { - this.hypervisor = hypervisor; - } + public HypervisorType getHypervisor() { + return hypervisor; + } + public void setHypervisor(HypervisorType hypervisor) { + this.hypervisor = hypervisor; + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java index c11da3d8078..ac50e9bde95 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentManagerSimpleImpl.java @@ -26,7 +26,6 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; @@ -66,6 +65,7 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa ClusterDao clusterDao; @Inject ClusterDetailsDao clusterDetailsDao; + @Override public boolean configure(String name, Map params) throws ConfigurationException { // TODO Auto-generated method stub @@ -92,16 +92,16 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa @Override public Answer easySend(Long hostId, Command cmd) { - try { - return this.send(hostId, cmd); - } catch (AgentUnavailableException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (OperationTimedoutException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; + try { + return this.send(hostId, cmd); + } catch (AgentUnavailableException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (OperationTimedoutException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; } protected void loadResource(Long hostId) { @@ -116,23 +116,23 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa ServerResource resource = null; if (host.getHypervisorType() == HypervisorType.XenServer) { - resource = new XcpOssResource(); - try { - resource.configure(host.getName(), params); - - } catch (ConfigurationException e) { - logger.debug("Failed to load resource:" + e.toString()); - } + resource = new XcpOssResource(); + try { + resource.configure(host.getName(), params); + + } catch (ConfigurationException e) { + logger.debug("Failed to load resource:" + e.toString()); + } } else if (host.getHypervisorType() == HypervisorType.KVM) { - resource = new LibvirtComputingResource(); - try { - params.put("public.network.device", "cloudbr0"); - params.put("private.network.device", "cloudbr0"); - resource.configure(host.getName(), params); - } catch (ConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + resource = new LibvirtComputingResource(); + try { + params.put("public.network.device", "cloudbr0"); + params.put("private.network.device", "cloudbr0"); + resource.configure(host.getName(), params); + } catch (ConfigurationException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } else if (host.getHypervisorType() == HypervisorType.VMware) { ClusterVO cluster = clusterDao.findById(host.getClusterId()); String url = clusterDetailsDao.findDetail(cluster.getId(), "url").getValue(); @@ -143,7 +143,8 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa String password = clusterDetailsDao.findDetail(cluster.getId(), "password").getValue(); VmwareServerDiscoverer discover = new VmwareServerDiscoverer(); - Map> resources = discover.find(host.getDataCenterId(), host.getPodId(), host.getClusterId(), uri, userName, password, null); + Map> resources = discover.find(host.getDataCenterId(), + host.getPodId(), host.getClusterId(), uri, userName, password, null); for (Map.Entry> entry : resources.entrySet()) { resource = entry.getKey(); } @@ -168,7 +169,8 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa } @Override - public synchronized Answer send(Long hostId, Command cmd) throws AgentUnavailableException, OperationTimedoutException { + public synchronized Answer send(Long hostId, Command cmd) throws AgentUnavailableException, + OperationTimedoutException { ServerResource resource = hostResourcesMap.get(hostId); if (resource == null) { loadResource(hostId); @@ -190,7 +192,8 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa } @Override - public Answer[] send(Long hostId, Commands cmds, int timeout) throws AgentUnavailableException, OperationTimedoutException { + public Answer[] send(Long hostId, Commands cmds, int timeout) throws AgentUnavailableException, + OperationTimedoutException { // TODO Auto-generated method stub return null; } @@ -231,7 +234,6 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } - @Override public boolean tapLoadingAgents(Long hostId, TapAgentsAction action) { // TODO Auto-generated method stub @@ -239,7 +241,8 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa } @Override - public AgentAttache handleDirectConnectAgent(HostVO host, StartupCommand[] cmds, ServerResource resource, boolean forRebalance) throws ConnectionException { + public AgentAttache handleDirectConnectAgent(HostVO host, StartupCommand[] cmds, ServerResource resource, + boolean forRebalance) throws ConnectionException { // TODO Auto-generated method stub return null; } @@ -286,10 +289,10 @@ public class DirectAgentManagerSimpleImpl extends ManagerBase implements AgentMa return null; } - @Override - public void disconnectWithInvestigation(long hostId, Event event) { - // TODO Auto-generated method stub + @Override + public void disconnectWithInvestigation(long hostId, Event event) { + // TODO Auto-generated method stub - } + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index ab09c50ff5c..d0cfa395d77 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -50,11 +50,11 @@ import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceState; -@ContextConfiguration(locations="classpath:/storageContext.xml") +@ContextConfiguration(locations = "classpath:/storageContext.xml") public class DirectAgentTest extends CloudStackTestNGBase { @Inject AgentManager agentMgr; - @Inject + @Inject HostDao hostDao; @Inject HostPodDao podDao; @@ -65,7 +65,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { private long dcId; private long clusterId; private long hostId; - + @Test(priority = -1) public void setUp() { HostVO host = hostDao.findByGuid(getHostGuid()); @@ -75,23 +75,24 @@ public class DirectAgentTest extends CloudStackTestNGBase { clusterId = host.getClusterId(); return; } - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); dc = dcDao.persist(dc); dcId = dc.getId(); - //create pod + // create pod - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), getHostGateway(), getHostCidr(), 8, "test"); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), getHostGateway(), getHostCidr(), 8, + "test"); pod = podDao.persist(pod); - //create xen cluster + // create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); cluster.setHypervisorType(HypervisorType.XenServer.toString()); cluster.setClusterType(ClusterType.CloudManaged); cluster.setManagedState(ManagedState.Managed); cluster = clusterDao.persist(cluster); clusterId = cluster.getId(); - //create xen host + // create xen host host = new HostVO(getHostGuid()); host.setName("devcloud xen host"); @@ -109,7 +110,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { host = hostDao.persist(host); hostId = host.getId(); } - + @Test public void testInitResource() { ReadyCommand cmd = new ReadyCommand(dcId); @@ -123,23 +124,24 @@ public class DirectAgentTest extends CloudStackTestNGBase { e.printStackTrace(); } } - + @Test public void testDownloadTemplate() { ImageStoreTO image = Mockito.mock(ImageStoreTO.class); PrimaryDataStoreTO primaryStore = Mockito.mock(PrimaryDataStoreTO.class); Mockito.when(primaryStore.getUuid()).thenReturn(getLocalStorageUuid()); - //Mockito.when(image.get).thenReturn(primaryStore); - + // Mockito.when(image.get).thenReturn(primaryStore); + ImageStoreTO imageStore = Mockito.mock(ImageStoreTO.class); Mockito.when(imageStore.getProtocol()).thenReturn("http"); - + TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class); Mockito.when(template.getPath()).thenReturn(getTemplateUrl()); Mockito.when(template.getImageDataStore()).thenReturn(imageStore); - - //Mockito.when(image.getTemplate()).thenReturn(template); - //CopyTemplateToPrimaryStorageCmd cmd = new CopyTemplateToPrimaryStorageCmd(image); + + // Mockito.when(image.getTemplate()).thenReturn(template); + // CopyTemplateToPrimaryStorageCmd cmd = new + // CopyTemplateToPrimaryStorageCmd(image); Command cmd = null; try { agentMgr.send(hostId, cmd); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java deleted file mode 100644 index 2e57ea9cb4a..00000000000 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHostEndpointRpcServerDirectCallResource.java +++ /dev/null @@ -1,70 +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.test; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.HostEndpointRpcServer; -import org.apache.cloudstack.storage.RemoteHostEndPoint; -import org.apache.log4j.Logger; - -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.utils.component.ComponentContext; - - -public class MockHostEndpointRpcServerDirectCallResource implements HostEndpointRpcServer { - private static final Logger s_logger = Logger.getLogger(MockHostEndpointRpcServerDirectCallResource.class); - private ScheduledExecutorService executor; - @Inject - AgentManager agentMgr; - public MockHostEndpointRpcServerDirectCallResource() { - executor = Executors.newScheduledThreadPool(10); - } - - public void sendCommandAsync(RemoteHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { - // new MockRpcCallBack(host.getHostId(), command, callback); - MockRpcCallBack run = ComponentContext.inject(MockRpcCallBack.class); - run.setCallback(callback); - run.setCmd(command); - run.setHostId(host.getId()); - executor.schedule(run, 10, TimeUnit.SECONDS); - } - - @Override - public Answer sendCommand(RemoteHostEndPoint host, Command command) { - Answer answer; - try { - answer = agentMgr.send(host.getId(), command); - return answer; - } catch (AgentUnavailableException e) { - return null; - } catch (OperationTimedoutException e) { - return null; - } - } -} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervisorHostEndPointRpcServer.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervisorHostEndPointRpcServer.java deleted file mode 100644 index e65963908d3..00000000000 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockHypervisorHostEndPointRpcServer.java +++ /dev/null @@ -1,72 +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.test; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.HostEndpointRpcServer; -import org.apache.cloudstack.storage.RemoteHostEndPoint; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; - -public class MockHypervisorHostEndPointRpcServer implements HostEndpointRpcServer { - private ScheduledExecutorService executor; - public MockHypervisorHostEndPointRpcServer() { - executor = Executors.newScheduledThreadPool(10); - } - - protected class MockRpcCallBack implements Runnable { - private final Command cmd; - private final AsyncCompletionCallback callback; - public MockRpcCallBack(Command cmd, final AsyncCompletionCallback callback) { - this.cmd = cmd; - this.callback = callback; - } - @Override - public void run() { - try { - Answer answer = new Answer(cmd, false, "unknown command"); - /*if (cmd instanceof CopyTemplateToPrimaryStorageCmd) { - answer = new CopyTemplateToPrimaryStorageAnswer(cmd, UUID.randomUUID().toString()); - } else if (cmd instanceof CreateVolumeFromBaseImageCommand) { - answer = new CreateVolumeAnswer(cmd, UUID.randomUUID().toString()); - }*/ - - callback.complete(answer); - } catch (Exception e) { - e.printStackTrace(); - } - } - - } - - public void sendCommandAsync(RemoteHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { - executor.schedule(new MockRpcCallBack(command, callback), 10, TimeUnit.SECONDS); - } - - @Override - public Answer sendCommand(RemoteHostEndPoint host, Command command) { - // TODO Auto-generated method stub - return null; - } -} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java index 28a586f83e5..26c1a634b1e 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java @@ -27,12 +27,13 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.DeleteSnapshotBackupCommand; public class MockLocalHostEndPoint extends LocalHostEndpoint { - @Override - public Answer sendMessage(Command cmd) { - if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand) || (cmd instanceof DeleteSnapshotBackupCommand)) { - return resource.executeRequest(cmd); - } - // TODO Auto-generated method stub - return new Answer(cmd, false, "unsupported command:" + cmd.toString()); - } + @Override + public Answer sendMessage(Command cmd) { + if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand) + || (cmd instanceof DeleteSnapshotBackupCommand)) { + return resource.executeRequest(cmd); + } + // TODO Auto-generated method stub + return new Answer(cmd, false, "unsupported command:" + cmd.toString()); + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockRpcCallBack.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockRpcCallBack.java index e0ffb48281a..60308da274b 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockRpcCallBack.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockRpcCallBack.java @@ -32,20 +32,20 @@ public class MockRpcCallBack implements Runnable { AgentManager agentMgr; private Command cmd; private long hostId; - private AsyncCompletionCallback callback; - + private AsyncCompletionCallback callback; + public void setCmd(Command cmd) { this.cmd = cmd; } - + public void setHostId(long hostId) { this.hostId = hostId; } - + public void setCallback(AsyncCompletionCallback callback) { this.callback = callback; } - + @Override @DB public void run() { @@ -56,5 +56,5 @@ public class MockRpcCallBack implements Runnable { s_logger.debug("send command failed:", e); } } - + } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java index edec9770cfa..52ccf410c8d 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockStorageMotionStrategy.java @@ -32,7 +32,6 @@ import com.cloud.host.Host; public class MockStorageMotionStrategy implements DataMotionStrategy { - @Override public boolean canHandle(DataObject srcData, DataObject destData) { // TODO Auto-generated method stub @@ -45,8 +44,7 @@ public class MockStorageMotionStrategy implements DataMotionStrategy { } @Override - public Void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { + public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { CopyCommandResult result = new CopyCommandResult("something", null); callback.complete(result); return null; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java index d88e6dad176..0bb724d10e4 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/S3TemplateTest.java @@ -42,6 +42,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreHelper; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -59,42 +60,41 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.download.DownloadMonitorImpl; import com.cloud.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) - +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class S3TemplateTest extends CloudStackTestNGBase { - @Inject - DataCenterDao dcDao; - ImageStoreVO imageStore; - ImageStoreDetailVO imageStoreDetail; - @Inject - ImageStoreDao imageStoreDao; - @Inject - TemplateService templateSvr; - @Inject - VMTemplateDao templateDao; - @Inject - TemplateDataFactory templateFactory; - @Inject - DataStoreManager dataStoreMgr; - @Inject - EndPointSelector epSelector; - @Inject - DownloadMonitorImpl downloadMonitor; - @Inject - ImageStoreHelper imageStoreHelper; - @Inject - StorageCacheManager cacheMgr; - long dcId; - long templateId; + @Inject + DataCenterDao dcDao; + ImageStoreVO imageStore; + ImageStoreDetailVO imageStoreDetail; + @Inject + ImageStoreDao imageStoreDao; + @Inject + TemplateService templateSvr; + @Inject + VMTemplateDao templateDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + DataStoreManager dataStoreMgr; + @Inject + EndPointSelector epSelector; + @Inject + DownloadMonitorImpl downloadMonitor; + @Inject + ImageStoreHelper imageStoreHelper; + @Inject + StorageCacheManager cacheMgr; + long dcId; + long templateId; - @Test(priority = -1) - public void setUp() { - ComponentContext.initComponentsLifeCycle(); - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); - dc = dcDao.persist(dc); - dcId = dc.getId(); + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); // add s3 image store Map sParams = new HashMap(); @@ -121,55 +121,54 @@ public class S3TemplateTest extends CloudStackTestNGBase { cParams.put("zoneId", dcId); this.imageStoreHelper.createImageStore(cParams); + VMTemplateVO image = new VMTemplateVO(); + image.setTemplateType(TemplateType.SYSTEM); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(false); + image.setFeatured(false); + image.setRequiresHvm(false); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(false); + image.setEnableSshKey(false); + image.setGuestOSId(133); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + image.setAccountId(2); + image = templateDao.persist(image); + templateId = image.getId(); - VMTemplateVO image = new VMTemplateVO(); - image.setTemplateType(TemplateType.SYSTEM); - image.setUrl(this.getTemplateUrl()); - image.setUniqueName(UUID.randomUUID().toString()); - image.setName(UUID.randomUUID().toString()); - image.setPublicTemplate(false); - image.setFeatured(false); - image.setRequiresHvm(false); - image.setBits(64); - image.setFormat(Storage.ImageFormat.VHD); - image.setEnablePassword(false); - image.setEnableSshKey(false); - image.setGuestOSId(133); - image.setBootable(true); - image.setPrepopulate(true); - image.setCrossZones(true); - image.setExtractable(true); - image.setAccountId(2); - image = templateDao.persist(image); - templateId = image.getId(); + // inject mockito + LocalHostEndpoint ep = new LocalHostEndpoint(); + ep.setResource(new MockLocalNfsSecondaryStorageResource()); + Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep); + } - // inject mockito - LocalHostEndpoint ep = new LocalHostEndpoint(); - ep.setResource(new MockLocalNfsSecondaryStorageResource()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); - } - - @Test(priority = 1) - public void registerTemplate() { - TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); - DataStore store = dataStoreMgr.getImageStore(dcId); - AsyncCallFuture future = new AsyncCallFuture(); - templateSvr.createTemplateAsync(template, store, future); - try { - TemplateApiResult result = future.get(); - assertTrue(result.isSuccess(), "failed to register template: " + result.getResult()); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - assertTrue(false, e.getMessage()); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - assertTrue(false, e.getMessage()); - } - } + @Test(priority = 1) + public void registerTemplate() { + TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); + DataStore store = dataStoreMgr.getImageStore(dcId); + AsyncCallFuture future = new AsyncCallFuture(); + templateSvr.createTemplateAsync(template, store, future); + try { + TemplateApiResult result = future.get(); + assertTrue(result.isSuccess(), "failed to register template: " + result.getResult()); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + assertTrue(false, e.getMessage()); + } + } @Test(priority = 2) public void copyTemplateToCache() { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 503b8d36350..8210dfe45bd 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -44,7 +44,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; -import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource; @@ -56,6 +55,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; @@ -97,7 +97,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class SnapshotTest extends CloudStackTestNGBase { @Inject ImageStoreDao imageStoreDao; @@ -142,7 +142,8 @@ public class SnapshotTest extends CloudStackTestNGBase { ResourceManager resourceMgr; @Inject VolumeDataFactory volFactory; - @Inject SnapshotDataFactory snapshotFactory; + @Inject + SnapshotDataFactory snapshotFactory; @Inject List snapshotStrategies; @Inject @@ -158,6 +159,7 @@ public class SnapshotTest extends CloudStackTestNGBase { VMTemplateVO image; String imageStoreName = "testImageStore"; RemoteHostEndPoint remoteEp; + @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -169,24 +171,25 @@ public class SnapshotTest extends CloudStackTestNGBase { podId = host.getPodId(); imageStore = this.imageStoreDao.findByName(imageStoreName); } else { - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); dc = dcDao.persist(dc); dcId = dc.getId(); - //create pod + // create pod - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), + this.getHostCidr(), 8, "test"); pod = podDao.persist(pod); podId = pod.getId(); - //create xen cluster + // create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); cluster.setHypervisorType(this.getHypervisor().toString()); cluster.setClusterType(ClusterType.CloudManaged); cluster.setManagedState(ManagedState.Managed); cluster = clusterDao.persist(cluster); clusterId = cluster.getId(); - //create xen host + // create xen host host = new HostVO(this.getHostGuid()); host.setName("devcloud xen host"); @@ -235,16 +238,17 @@ public class SnapshotTest extends CloudStackTestNGBase { image = imageDataDao.persist(image); - /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); - - templateStore.setDataStoreId(imageStore.getId()); - templateStore.setDownloadPercent(100); - templateStore.setDownloadState(Status.DOWNLOADED); - templateStore.setDownloadUrl(imageStore.getUrl()); - templateStore.setInstallPath(this.getImageInstallPath()); - templateStore.setTemplateId(image.getId()); - templateStoreDao.persist(templateStore);*/ - + /* + * TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); + * + * templateStore.setDataStoreId(imageStore.getId()); + * templateStore.setDownloadPercent(100); + * templateStore.setDownloadState(Status.DOWNLOADED); + * templateStore.setDownloadUrl(imageStore.getUrl()); + * templateStore.setInstallPath(this.getImageInstallPath()); + * templateStore.setTemplateId(image.getId()); + * templateStoreDao.persist(templateStore); + */ DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image); @@ -257,20 +261,24 @@ public class SnapshotTest extends CloudStackTestNGBase { templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); - } @Override protected void injectMockito() { List hosts = new ArrayList(); hosts.add(this.host); - Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); + Mockito.when( + resourceMgr.listAllUpAndEnabledHosts((Type) Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), + Matchers.anyLong())).thenReturn(hosts); - remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(remoteEp); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(remoteEp); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp); - Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId()); + remoteEp = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), + this.host.getPublicIpAddress()); + Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn( + remoteEp); + Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(remoteEp); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp); + Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))) + .thenReturn(this.host.getId()); } @@ -282,26 +290,27 @@ public class SnapshotTest extends CloudStackTestNGBase { return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); } - /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); - Map params = new HashMap(); - URI uri = new URI(this.getPrimaryStorageUrl()); - params.put("url", this.getPrimaryStorageUrl()); - params.put("server", uri.getHost()); - params.put("path", uri.getPath()); - params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); - params.put("zoneId", dcId); - params.put("clusterId", clusterId); - params.put("name", this.primaryName); - params.put("port", 1); - params.put("podId", this.podId); - params.put("roles", DataStoreRole.Primary.toString()); - params.put("uuid", uuid); - params.put("providerName", String.valueOf(provider.getName())); - - DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - DataStore store = lifeCycle.initialize(params); - ClusterScope scope = new ClusterScope(clusterId, podId, dcId); - lifeCycle.attachCluster(store, scope);*/ + /* + * DataStoreProvider provider = + * dataStoreProviderMgr.getDataStoreProvider + * ("cloudstack primary data store provider"); Map + * params = new HashMap(); URI uri = new + * URI(this.getPrimaryStorageUrl()); params.put("url", + * this.getPrimaryStorageUrl()); params.put("server", + * uri.getHost()); params.put("path", uri.getPath()); + * params.put("protocol", + * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId", + * dcId); params.put("clusterId", clusterId); params.put("name", + * this.primaryName); params.put("port", 1); params.put("podId", + * this.podId); params.put("roles", + * DataStoreRole.Primary.toString()); params.put("uuid", uuid); + * params.put("providerName", String.valueOf(provider.getName())); + * + * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + * DataStore store = lifeCycle.initialize(params); ClusterScope + * scope = new ClusterScope(clusterId, podId, dcId); + * lifeCycle.attachCluster(store, scope); + */ StoragePoolVO pool = new StoragePoolVO(); pool.setClusterId(clusterId); @@ -327,8 +336,9 @@ public class SnapshotTest extends CloudStackTestNGBase { private SnapshotVO createSnapshotInDb(VolumeInfo volume) { Snapshot.Type snapshotType = Snapshot.Type.MANUAL; - SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID().toString(), - (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), HypervisorType.XenServer); + SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), 2, 1, volume.getId(), 1L, UUID.randomUUID() + .toString(), (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), + HypervisorType.XenServer); return this.snapshotDao.persist(snapshotVO); } @@ -341,14 +351,14 @@ public class SnapshotTest extends CloudStackTestNGBase { return volume; } - public VolumeInfo createCopyBaseImage() { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, + this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); VolumeApiResult result; try { @@ -372,27 +382,27 @@ public class SnapshotTest extends CloudStackTestNGBase { SnapshotInfo newSnapshot = null; for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { - newSnapshot = strategy.takeSnapshot(snapshot); + newSnapshot = strategy.takeSnapshot(snapshot); } } AssertJUnit.assertNotNull(newSnapshot); LocalHostEndpoint ep = new MockLocalHostEndPoint(); ep.setResource(new MockLocalNfsSecondaryStorageResource()); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); - //delete snapshot + // delete snapshot for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { - strategy.deleteSnapshot(newSnapshot.getId()); + strategy.deleteSnapshot(newSnapshot.getId()); } } - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(remoteEp); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp); } private VMTemplateVO createTemplateInDb() { - VMTemplateVO image = new VMTemplateVO(); + VMTemplateVO image = new VMTemplateVO(); image.setTemplateType(TemplateType.USER); image.setUniqueName(UUID.randomUUID().toString()); @@ -435,21 +445,21 @@ public class SnapshotTest extends CloudStackTestNGBase { @Test public void deleteSnapshot() { - VolumeInfo vol = createCopyBaseImage(); + VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); SnapshotInfo newSnapshot = null; for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { - newSnapshot = strategy.takeSnapshot(snapshot); + newSnapshot = strategy.takeSnapshot(snapshot); } } AssertJUnit.assertNotNull(newSnapshot); - //create another snapshot + // create another snapshot for (SnapshotStrategy strategy : this.snapshotStrategies) { if (strategy.canHandle(snapshot)) { - strategy.deleteSnapshot(newSnapshot.getId()); + strategy.deleteSnapshot(newSnapshot.getId()); } } @@ -471,12 +481,11 @@ public class SnapshotTest extends CloudStackTestNGBase { AssertJUnit.assertTrue(result); LocalHostEndpoint ep = new LocalHostEndpoint(); ep.setResource(new MockLocalNfsSecondaryStorageResource()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep); VMTemplateVO templateVO = createTemplateInDb(); TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); } - } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java index 2ac6dac4c16..53a6464304a 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageFactoryBean.java @@ -16,16 +16,15 @@ // under the License. package org.apache.cloudstack.storage.test; - import org.mockito.Mockito; import org.springframework.beans.factory.FactoryBean; /** - * A {@link FactoryBean} for creating mocked beans based on Mockito so that they + * A {@link FactoryBean} for creating mocked beans based on Mockito so that they * can be {@link @Autowired} into Spring test configurations. - * + * * @author Mattias Severson, Jayway - * + * * @see FactoryBean * @see org.mockito.Mockito */ @@ -35,7 +34,9 @@ public class StorageFactoryBean implements FactoryBean { /** * Creates a Mockito mock instance of the provided class. - * @param classToBeMocked The class to be mocked. + * + * @param classToBeMocked + * The class to be mocked. */ public StorageFactoryBean(Class classToBeMocked) { this.classToBeMocked = classToBeMocked; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageTest.java index 0ee7fe0a431..5db3a0f09b0 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/StorageTest.java @@ -23,14 +23,13 @@ import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:resource/storageContext.xml") +@ContextConfiguration(locations = "classpath:resource/storageContext.xml") public class StorageTest { - @Test - public void test() { - fail("Not yet implemented"); - } + @Test + public void test() { + fail("Not yet implemented"); + } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java index c84fee5bcf9..da4c17b6041 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TemplateTest.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.cloudstack.storage.MockLocalNfsSecondaryStorageResource; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.annotations.Test; @@ -46,97 +47,90 @@ import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.dao.DataCenterDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage; -import com.cloud.storage.TemplateProfile; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.download.DownloadMonitorImpl; -import com.cloud.template.HypervisorTemplateAdapter; -import com.cloud.template.TemplateAdapter; import com.cloud.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) - +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class TemplateTest extends CloudStackTestNGBase { - @Inject - DataCenterDao dcDao; - ImageStoreVO imageStore; - @Inject - ImageStoreDao imageStoreDao; - @Inject - TemplateService templateSvr; - @Inject - VMTemplateDao templateDao; - @Inject - TemplateDataFactory templateFactory; - @Inject - DataStoreManager dataStoreMgr; - @Inject - EndPointSelector epSelector; - @Inject - DownloadMonitorImpl downloadMonitor; + @Inject + DataCenterDao dcDao; + ImageStoreVO imageStore; + @Inject + ImageStoreDao imageStoreDao; + @Inject + TemplateService templateSvr; + @Inject + VMTemplateDao templateDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + DataStoreManager dataStoreMgr; + @Inject + EndPointSelector epSelector; + @Inject + DownloadMonitorImpl downloadMonitor; + long dcId; + long templateId; - long dcId; - long templateId; + @Test(priority = -1) + public void setUp() { + ComponentContext.initComponentsLifeCycle(); - @Test(priority = -1) - public void setUp() { - ComponentContext.initComponentsLifeCycle(); + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); - dc = dcDao.persist(dc); - dcId = dc.getId(); + imageStore = new ImageStoreVO(); + imageStore.setName("test"); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName(DataStoreProvider.NFS_IMAGE); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore.setProtocol("nfs"); + imageStore = imageStoreDao.persist(imageStore); - imageStore = new ImageStoreVO(); - imageStore.setName("test"); - imageStore.setDataCenterId(dcId); - imageStore.setProviderName(DataStoreProvider.NFS_IMAGE); - imageStore.setRole(DataStoreRole.Image); - imageStore.setUrl(this.getSecondaryStorage()); - imageStore.setUuid(UUID.randomUUID().toString()); - imageStore.setProtocol("nfs"); - imageStore = imageStoreDao.persist(imageStore); + VMTemplateVO image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); - VMTemplateVO image = new VMTemplateVO(); - image.setTemplateType(TemplateType.USER); - image.setUrl(this.getTemplateUrl()); - image.setUniqueName(UUID.randomUUID().toString()); - image.setName(UUID.randomUUID().toString()); - image.setPublicTemplate(true); - image.setFeatured(true); - image.setRequiresHvm(true); - image.setBits(64); - image.setFormat(Storage.ImageFormat.VHD); - image.setEnablePassword(true); - image.setEnableSshKey(true); - image.setGuestOSId(1); - image.setBootable(true); - image.setPrepopulate(true); - image.setCrossZones(true); - image.setExtractable(true); - - - //image.setImageDataStoreId(storeId); - image = templateDao.persist(image); - templateId = image.getId(); + // image.setImageDataStoreId(storeId); + image = templateDao.persist(image); + templateId = image.getId(); // inject mockito LocalHostEndpoint ep = new LocalHostEndpoint(); ep.setResource(new MockLocalNfsSecondaryStorageResource()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); - } + Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); + } - @Test - public void registerTemplate() { - TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); - DataStore store = dataStoreMgr.getImageStore(dcId); - AsyncCallFuture future = new AsyncCallFuture(); - templateSvr.createTemplateAsync(template, store, future); + @Test + public void registerTemplate() { + TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); + DataStore store = dataStoreMgr.getImageStore(dcId); + AsyncCallFuture future = new AsyncCallFuture(); + templateSvr.createTemplateAsync(template, store, future); try { TemplateApiResult result = future.get(); assertTrue(result.isSuccess(), "failed to register template: " + result.getResult()); @@ -147,11 +141,11 @@ public class TemplateTest extends CloudStackTestNGBase { } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); - assertTrue(false, e.getMessage()); + assertTrue(false, e.getMessage()); } - } + } - // @Test + // @Test public void deleteTemplate() { TemplateInfo template = templateFactory.getTemplate(templateId, DataStoreRole.Image); DataStore store = dataStoreMgr.getImageStore(dcId); @@ -167,7 +161,7 @@ public class TemplateTest extends CloudStackTestNGBase { } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); - assertTrue(false, e.getMessage()); + assertTrue(false, e.getMessage()); } } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java index 8b10f7e3224..11d4931fd7d 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestHttp.java @@ -22,28 +22,21 @@ import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; import java.io.OutputStream; -import java.nio.channels.FileChannel; - import junit.framework.Assert; import org.apache.commons.httpclient.HttpException; -import org.apache.cxf.helpers.IOUtils; -import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.impl.client.DefaultHttpClient; import org.junit.Test; -import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; import org.testng.annotations.Parameters; -@ContextConfiguration(locations="classpath:/storageContext.xml") +@ContextConfiguration(locations = "classpath:/storageContext.xml") public class TestHttp extends AbstractTestNGSpringContextTests { @Test @Parameters("template-url") @@ -59,13 +52,13 @@ public class TestHttp extends AbstractTestNGSpringContextTests { System.out.println(response.getFirstHeader("Content-Length").getValue()); File localFile = new File("/tmp/test"); if (!localFile.exists()) { - localFile.createNewFile(); + localFile.createNewFile(); } - + HttpGet getMethod = new HttpGet(templateUrl); response = client.execute(getMethod); HttpEntity entity = response.getEntity(); - + output = new BufferedOutputStream(new FileOutputStream(localFile)); entity.writeTo(output); } catch (HttpException e) { @@ -83,7 +76,7 @@ public class TestHttp extends AbstractTestNGSpringContextTests { e.printStackTrace(); } } - + File f = new File("/tmp/test"); Assert.assertEquals(f.length(), length); } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java index b3ecd3c22cb..e85c3d8db35 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNG.java @@ -20,12 +20,11 @@ import junit.framework.Assert; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.testng.AbstractTestNGSpringContextTests; -import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests; -import org.testng.annotations.Parameters; import org.testng.annotations.Test; import com.cloud.utils.db.DB; -@ContextConfiguration(locations="classpath:/storageContext.xml") + +@ContextConfiguration(locations = "classpath:/storageContext.xml") public class TestNG extends AbstractTestNGSpringContextTests { @Test @DB diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java index 130ecd21980..515c5c80532 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/TestNGAop.java @@ -31,8 +31,7 @@ import com.cloud.utils.db.Transaction; public class TestNGAop implements IMethodInterceptor { @Override - public List intercept(List methods, - ITestContext context) { + public List intercept(List methods, ITestContext context) { for (IMethodInstance methodIns : methods) { ITestNGMethod method = methodIns.getMethod(); ConstructorOrMethod meth = method.getConstructorOrMethod(); @@ -44,8 +43,7 @@ public class TestNGAop implements IMethodInterceptor { } } } - - + // TODO Auto-generated method stub return methods; } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index 187d1f548cc..ef5c4caae96 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -40,7 +40,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; -import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -50,6 +49,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; @@ -88,7 +88,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class VolumeTest extends CloudStackTestNGBase { @Inject ImageStoreDao imageStoreDao; @@ -140,6 +140,7 @@ public class VolumeTest extends CloudStackTestNGBase { long primaryStoreId; VMTemplateVO image; String imageStoreName = "testImageStore"; + @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -151,24 +152,25 @@ public class VolumeTest extends CloudStackTestNGBase { podId = host.getPodId(); imageStore = this.imageStoreDao.findByName(imageStoreName); } else { - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); dc = dcDao.persist(dc); dcId = dc.getId(); - //create pod + // create pod - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), + this.getHostCidr(), 8, "test"); pod = podDao.persist(pod); podId = pod.getId(); - //create xen cluster + // create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); cluster.setHypervisorType(this.getHypervisor().toString()); cluster.setClusterType(ClusterType.CloudManaged); cluster.setManagedState(ManagedState.Managed); cluster = clusterDao.persist(cluster); clusterId = cluster.getId(); - //create xen host + // create xen host host = new HostVO(this.getHostGuid()); host.setName("devcloud xen host"); @@ -217,16 +219,17 @@ public class VolumeTest extends CloudStackTestNGBase { image = imageDataDao.persist(image); - /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); - - templateStore.setDataStoreId(imageStore.getId()); - templateStore.setDownloadPercent(100); - templateStore.setDownloadState(Status.DOWNLOADED); - templateStore.setDownloadUrl(imageStore.getUrl()); - templateStore.setInstallPath(this.getImageInstallPath()); - templateStore.setTemplateId(image.getId()); - templateStoreDao.persist(templateStore);*/ - + /* + * TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); + * + * templateStore.setDataStoreId(imageStore.getId()); + * templateStore.setDownloadPercent(100); + * templateStore.setDownloadState(Status.DOWNLOADED); + * templateStore.setDownloadUrl(imageStore.getUrl()); + * templateStore.setInstallPath(this.getImageInstallPath()); + * templateStore.setTemplateId(image.getId()); + * templateStoreDao.persist(templateStore); + */ DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image); @@ -238,20 +241,23 @@ public class VolumeTest extends CloudStackTestNGBase { templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); - } @Override protected void injectMockito() { List hosts = new ArrayList(); hosts.add(this.host); - Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); + Mockito.when( + resourceMgr.listAllUpAndEnabledHosts((Type) Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), + Matchers.anyLong())).thenReturn(hosts); - RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); - Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Mockito.anyLong(), Mockito.any(Command.class))).thenReturn(this.host.getId()); + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), + this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); + Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); + Mockito.when(hyGuruMgr.getGuruProcessedCommandTargetHost(Matchers.anyLong(), Matchers.any(Command.class))) + .thenReturn(this.host.getId()); } public DataStore createPrimaryDataStore() { @@ -262,26 +268,27 @@ public class VolumeTest extends CloudStackTestNGBase { return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); } - /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); - Map params = new HashMap(); - URI uri = new URI(this.getPrimaryStorageUrl()); - params.put("url", this.getPrimaryStorageUrl()); - params.put("server", uri.getHost()); - params.put("path", uri.getPath()); - params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); - params.put("zoneId", dcId); - params.put("clusterId", clusterId); - params.put("name", this.primaryName); - params.put("port", 1); - params.put("podId", this.podId); - params.put("roles", DataStoreRole.Primary.toString()); - params.put("uuid", uuid); - params.put("providerName", String.valueOf(provider.getName())); - - DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - DataStore store = lifeCycle.initialize(params); - ClusterScope scope = new ClusterScope(clusterId, podId, dcId); - lifeCycle.attachCluster(store, scope);*/ + /* + * DataStoreProvider provider = + * dataStoreProviderMgr.getDataStoreProvider + * ("cloudstack primary data store provider"); Map + * params = new HashMap(); URI uri = new + * URI(this.getPrimaryStorageUrl()); params.put("url", + * this.getPrimaryStorageUrl()); params.put("server", + * uri.getHost()); params.put("path", uri.getPath()); + * params.put("protocol", + * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId", + * dcId); params.put("clusterId", clusterId); params.put("name", + * this.primaryName); params.put("port", 1); params.put("podId", + * this.podId); params.put("roles", + * DataStoreRole.Primary.toString()); params.put("uuid", uuid); + * params.put("providerName", String.valueOf(provider.getName())); + * + * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + * DataStore store = lifeCycle.initialize(params); ClusterScope + * scope = new ClusterScope(clusterId, podId, dcId); + * lifeCycle.attachCluster(store, scope); + */ StoragePoolVO pool = new StoragePoolVO(); pool.setClusterId(clusterId); @@ -306,7 +313,8 @@ public class VolumeTest extends CloudStackTestNGBase { } private VolumeVO createVolume(Long templateId, long dataStoreId) { - VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000);; + VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); + ; volume.setPoolId(dataStoreId); volume = volumeDao.persist(volume); return volume; @@ -319,7 +327,8 @@ public class VolumeTest extends CloudStackTestNGBase { primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, + this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); try { VolumeApiResult result = future.get(); @@ -427,6 +436,5 @@ public class VolumeTest extends CloudStackTestNGBase { e.printStackTrace(); } - } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java index 9d5555a8d8a..4acc8dc7de8 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTestVmware.java @@ -39,7 +39,6 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; -import org.apache.cloudstack.engine.subsystem.api.storage.type.RootDisk; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.RemoteHostEndPoint; import org.apache.cloudstack.storage.command.CopyCmdAnswer; @@ -49,6 +48,7 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; @@ -87,7 +87,7 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class VolumeTestVmware extends CloudStackTestNGBase { @Inject ImageStoreDao imageStoreDao; @@ -139,6 +139,7 @@ public class VolumeTestVmware extends CloudStackTestNGBase { long primaryStoreId; VMTemplateVO image; String imageStoreName = "testImageStore"; + @Test(priority = -1) public void setUp() { ComponentContext.initComponentsLifeCycle(); @@ -150,17 +151,18 @@ public class VolumeTestVmware extends CloudStackTestNGBase { podId = host.getPodId(); imageStore = this.imageStoreDao.findByName(imageStoreName); } else { - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); dc = dcDao.persist(dc); dcId = dc.getId(); - //create pod + // create pod - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), + this.getHostCidr(), 8, "test"); pod = podDao.persist(pod); podId = pod.getId(); - //create xen cluster + // create xen cluster ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); cluster.setHypervisorType(HypervisorType.VMware.toString()); cluster.setClusterType(ClusterType.ExternalManaged); @@ -168,14 +170,14 @@ public class VolumeTestVmware extends CloudStackTestNGBase { cluster = clusterDao.persist(cluster); clusterId = cluster.getId(); - //setup vcenter + // setup vcenter ClusterDetailsVO clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "url", null); this.clusterDetailsDao.persist(clusterDetailVO); clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "username", null); this.clusterDetailsDao.persist(clusterDetailVO); clusterDetailVO = new ClusterDetailsVO(cluster.getId(), "password", null); this.clusterDetailsDao.persist(clusterDetailVO); - //create xen host + // create xen host host = new HostVO(this.getHostGuid()); host.setName("devcloud vmware host"); @@ -224,16 +226,17 @@ public class VolumeTestVmware extends CloudStackTestNGBase { image = imageDataDao.persist(image); - /*TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); - - templateStore.setDataStoreId(imageStore.getId()); - templateStore.setDownloadPercent(100); - templateStore.setDownloadState(Status.DOWNLOADED); - templateStore.setDownloadUrl(imageStore.getUrl()); - templateStore.setInstallPath(this.getImageInstallPath()); - templateStore.setTemplateId(image.getId()); - templateStoreDao.persist(templateStore);*/ - + /* + * TemplateDataStoreVO templateStore = new TemplateDataStoreVO(); + * + * templateStore.setDataStoreId(imageStore.getId()); + * templateStore.setDownloadPercent(100); + * templateStore.setDownloadState(Status.DOWNLOADED); + * templateStore.setDownloadUrl(imageStore.getUrl()); + * templateStore.setInstallPath(this.getImageInstallPath()); + * templateStore.setTemplateId(image.getId()); + * templateStoreDao.persist(templateStore); + */ DataStore store = this.dataStoreMgr.getDataStore(imageStore.getId(), DataStoreRole.Image); TemplateInfo template = templateFactory.getTemplate(image.getId(), DataStoreRole.Image); @@ -244,19 +247,21 @@ public class VolumeTestVmware extends CloudStackTestNGBase { templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); - } @Override protected void injectMockito() { List hosts = new ArrayList(); hosts.add(this.host); - Mockito.when(resourceMgr.listAllUpAndEnabledHosts((Type) Mockito.any(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong())).thenReturn(hosts); + Mockito.when( + resourceMgr.listAllUpAndEnabledHosts((Type) Matchers.any(), Matchers.anyLong(), Matchers.anyLong(), + Matchers.anyLong())).thenReturn(hosts); - RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); - Mockito.when(epSelector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataObject.class))).thenReturn(ep); - Mockito.when(epSelector.select(Mockito.any(DataStore.class))).thenReturn(ep); + RemoteHostEndPoint ep = RemoteHostEndPoint.getHypervisorHostEndPoint(this.host.getId(), + this.host.getPrivateIpAddress(), this.host.getPublicIpAddress()); + Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataObject.class))).thenReturn(ep); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); } public DataStore createPrimaryDataStore() { @@ -267,26 +272,27 @@ public class VolumeTestVmware extends CloudStackTestNGBase { return this.dataStoreMgr.getPrimaryDataStore(pools.get(0).getId()); } - /*DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("cloudstack primary data store provider"); - Map params = new HashMap(); - URI uri = new URI(this.getPrimaryStorageUrl()); - params.put("url", this.getPrimaryStorageUrl()); - params.put("server", uri.getHost()); - params.put("path", uri.getPath()); - params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); - params.put("zoneId", dcId); - params.put("clusterId", clusterId); - params.put("name", this.primaryName); - params.put("port", 1); - params.put("podId", this.podId); - params.put("roles", DataStoreRole.Primary.toString()); - params.put("uuid", uuid); - params.put("providerName", String.valueOf(provider.getName())); - - DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - DataStore store = lifeCycle.initialize(params); - ClusterScope scope = new ClusterScope(clusterId, podId, dcId); - lifeCycle.attachCluster(store, scope);*/ + /* + * DataStoreProvider provider = + * dataStoreProviderMgr.getDataStoreProvider + * ("cloudstack primary data store provider"); Map + * params = new HashMap(); URI uri = new + * URI(this.getPrimaryStorageUrl()); params.put("url", + * this.getPrimaryStorageUrl()); params.put("server", + * uri.getHost()); params.put("path", uri.getPath()); + * params.put("protocol", + * Storage.StoragePoolType.NetworkFilesystem); params.put("zoneId", + * dcId); params.put("clusterId", clusterId); params.put("name", + * this.primaryName); params.put("port", 1); params.put("podId", + * this.podId); params.put("roles", + * DataStoreRole.Primary.toString()); params.put("uuid", uuid); + * params.put("providerName", String.valueOf(provider.getName())); + * + * DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + * DataStore store = lifeCycle.initialize(params); ClusterScope + * scope = new ClusterScope(clusterId, podId, dcId); + * lifeCycle.attachCluster(store, scope); + */ StoragePoolVO pool = new StoragePoolVO(); pool.setClusterId(clusterId); @@ -311,20 +317,22 @@ public class VolumeTestVmware extends CloudStackTestNGBase { } private VolumeVO createVolume(Long templateId, long dataStoreId) { - VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000);; + VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); + ; volume.setPoolId(dataStoreId); volume = volumeDao.persist(volume); return volume; } - //@Test + // @Test public void testCopyBaseImage() { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(image.getId(), primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); + AsyncCallFuture future = this.volumeService.createVolumeFromTemplateAsync(volInfo, + this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); try { VolumeApiResult result = future.get(); @@ -432,6 +440,5 @@ public class VolumeTestVmware extends CloudStackTestNGBase { e.printStackTrace(); } - } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java index 4e221010190..42b0463c71b 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/volumeServiceTest.java @@ -50,6 +50,7 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.testng.Assert; @@ -82,50 +83,50 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.utils.component.ComponentContext; -@ContextConfiguration(locations={"classpath:/storageContext.xml"}) +@ContextConfiguration(locations = { "classpath:/storageContext.xml" }) public class volumeServiceTest extends CloudStackTestNGBase { - //@Inject - //ImageDataStoreProviderManager imageProviderMgr; - @Inject - TemplateService imageService; - @Inject - VolumeService volumeService; - @Inject - VMTemplateDao imageDataDao; - @Inject - VolumeDao volumeDao; - @Inject - HostDao hostDao; - @Inject - HostPodDao podDao; - @Inject - ClusterDao clusterDao; - @Inject - DataCenterDao dcDao; - @Inject - PrimaryDataStoreDao primaryStoreDao; - @Inject - DataStoreProviderManager dataStoreProviderMgr; - @Inject - AgentManager agentMgr; - @Inject - EndPointSelector selector; - @Inject - TemplateDataFactory imageDataFactory; - @Inject - VolumeDataFactory volumeFactory; - @Inject - ImageStoreDao imageStoreDao; - ImageStoreVO imageStore; - Long dcId; - Long clusterId; - Long podId; - HostVO host; - String primaryName = "my primary data store"; - DataStore primaryStore; + // @Inject + // ImageDataStoreProviderManager imageProviderMgr; + @Inject + TemplateService imageService; + @Inject + VolumeService volumeService; + @Inject + VMTemplateDao imageDataDao; + @Inject + VolumeDao volumeDao; + @Inject + HostDao hostDao; + @Inject + HostPodDao podDao; + @Inject + ClusterDao clusterDao; + @Inject + DataCenterDao dcDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + @Inject + DataStoreProviderManager dataStoreProviderMgr; + @Inject + AgentManager agentMgr; + @Inject + EndPointSelector selector; + @Inject + TemplateDataFactory imageDataFactory; + @Inject + VolumeDataFactory volumeFactory; + @Inject + ImageStoreDao imageStoreDao; + ImageStoreVO imageStore; + Long dcId; + Long clusterId; + Long podId; + HostVO host; + String primaryName = "my primary data store"; + DataStore primaryStore; @Test(priority = -1) - public void setUp() { + public void setUp() { ComponentContext.initComponentsLifeCycle(); host = hostDao.findByGuid(this.getHostGuid()); @@ -135,51 +136,52 @@ public class volumeServiceTest extends CloudStackTestNGBase { podId = host.getPodId(); return; } - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); - dc = dcDao.persist(dc); - dcId = dc.getId(); - //create pod + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + // create pod - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), this.getHostCidr(), 8, "test"); - pod = podDao.persist(pod); - podId = pod.getId(); - //create xen cluster - ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); - cluster.setHypervisorType(HypervisorType.XenServer.toString()); - cluster.setClusterType(ClusterType.CloudManaged); - cluster.setManagedState(ManagedState.Managed); - cluster = clusterDao.persist(cluster); - clusterId = cluster.getId(); - //create xen host + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), this.getHostGateway(), + this.getHostCidr(), 8, "test"); + pod = podDao.persist(pod); + podId = pod.getId(); + // create xen cluster + ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); + cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setClusterType(ClusterType.CloudManaged); + cluster.setManagedState(ManagedState.Managed); + cluster = clusterDao.persist(cluster); + clusterId = cluster.getId(); + // create xen host - host = new HostVO(this.getHostGuid()); - host.setName("devcloud xen host"); - host.setType(Host.Type.Routing); - host.setPrivateIpAddress(this.getHostIp()); - host.setDataCenterId(dc.getId()); - host.setVersion("6.0.1"); - host.setAvailable(true); - host.setSetup(true); - host.setPodId(podId); - host.setLastPinged(0); - host.setResourceState(ResourceState.Enabled); - host.setHypervisorType(HypervisorType.XenServer); - host.setClusterId(cluster.getId()); + host = new HostVO(this.getHostGuid()); + host.setName("devcloud xen host"); + host.setType(Host.Type.Routing); + host.setPrivateIpAddress(this.getHostIp()); + host.setDataCenterId(dc.getId()); + host.setVersion("6.0.1"); + host.setAvailable(true); + host.setSetup(true); + host.setPodId(podId); + host.setLastPinged(0); + host.setResourceState(ResourceState.Enabled); + host.setHypervisorType(HypervisorType.XenServer); + host.setClusterId(cluster.getId()); - host = hostDao.persist(host); + host = hostDao.persist(host); - imageStore = new ImageStoreVO(); - imageStore.setName("test"); - imageStore.setDataCenterId(dcId); - imageStore.setProviderName("CloudStack ImageStore Provider"); - imageStore.setRole(DataStoreRole.Image); - imageStore.setUrl(this.getSecondaryStorage()); - imageStore.setUuid(UUID.randomUUID().toString()); - imageStore = imageStoreDao.persist(imageStore); + imageStore = new ImageStoreVO(); + imageStore.setName("test"); + imageStore.setDataCenterId(dcId); + imageStore.setProviderName("CloudStack ImageStore Provider"); + imageStore.setRole(DataStoreRole.Image); + imageStore.setUrl(this.getSecondaryStorage()); + imageStore.setUuid(UUID.randomUUID().toString()); + imageStore = imageStoreDao.persist(imageStore); - } + } @Override protected void injectMockito() { @@ -189,74 +191,79 @@ public class volumeServiceTest extends CloudStackTestNGBase { List results = new ArrayList(); results.add(host); Mockito.when(hostDao.listAll()).thenReturn(results); - Mockito.when(hostDao.findById(Mockito.anyLong())).thenReturn(host); - Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); + Mockito.when(hostDao.findById(Matchers.anyLong())).thenReturn(host); + Mockito.when(hostDao.findHypervisorHostInCluster(Matchers.anyLong())).thenReturn(results); List eps = new ArrayList(); - eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress(), host.getPublicIpAddress())); - Mockito.when(selector.selectAll(Mockito.any(DataStore.class))).thenReturn(eps); - Mockito.when(selector.select(Mockito.any(DataObject.class))).thenReturn(eps.get(0)); - Mockito.when(selector.select(Mockito.any(DataObject.class), Mockito.any(DataObject.class))).thenReturn(eps.get(0)); + eps.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), + host.getPublicIpAddress())); + Mockito.when(selector.selectAll(Matchers.any(DataStore.class))).thenReturn(eps); + Mockito.when(selector.select(Matchers.any(DataObject.class))).thenReturn(eps.get(0)); + Mockito.when(selector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn( + eps.get(0)); } - private VMTemplateVO createImageData() { - VMTemplateVO image = new VMTemplateVO(); - image.setTemplateType(TemplateType.USER); - image.setUrl(this.getTemplateUrl()); - image.setUniqueName(UUID.randomUUID().toString()); - image.setName(UUID.randomUUID().toString()); - image.setPublicTemplate(true); - image.setFeatured(true); - image.setRequiresHvm(true); - image.setBits(64); - image.setFormat(Storage.ImageFormat.VHD); - image.setEnablePassword(true); - image.setEnableSshKey(true); - image.setGuestOSId(1); - image.setBootable(true); - image.setPrepopulate(true); - image.setCrossZones(true); - image.setExtractable(true); + private VMTemplateVO createImageData() { + VMTemplateVO image = new VMTemplateVO(); + image.setTemplateType(TemplateType.USER); + image.setUrl(this.getTemplateUrl()); + image.setUniqueName(UUID.randomUUID().toString()); + image.setName(UUID.randomUUID().toString()); + image.setPublicTemplate(true); + image.setFeatured(true); + image.setRequiresHvm(true); + image.setBits(64); + image.setFormat(Storage.ImageFormat.VHD); + image.setEnablePassword(true); + image.setEnableSshKey(true); + image.setGuestOSId(1); + image.setBootable(true); + image.setPrepopulate(true); + image.setCrossZones(true); + image.setExtractable(true); + // image.setImageDataStoreId(storeId); + image = imageDataDao.persist(image); - //image.setImageDataStoreId(storeId); - image = imageDataDao.persist(image); + return image; + } + private TemplateInfo createTemplate() { + try { + DataStore store = createImageStore(); + VMTemplateVO image = createImageData(); + TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store); + // AsyncCallFuture future = + // imageService.createTemplateAsync(template, store); + // future.get(); + template = imageDataFactory.getTemplate(image.getId(), store); + /* + * imageProviderMgr.configure("image Provider", new HashMap()); VMTemplateVO image = createImageData(); + * ImageDataStoreProvider defaultProvider = + * imageProviderMgr.getProvider("DefaultProvider"); + * ImageDataStoreLifeCycle lifeCycle = + * defaultProvider.getLifeCycle(); ImageDataStore store = + * lifeCycle.registerDataStore("defaultHttpStore", new + * HashMap()); + * imageService.registerTemplate(image.getId(), + * store.getImageDataStoreId()); TemplateEntity te = + * imageService.getTemplateEntity(image.getId()); return te; + */ + return template; + } catch (Exception e) { + Assert.fail("failed", e); + return null; + } + } - return image; - } + // @Test + public void createTemplateTest() { + createTemplate(); + } - private TemplateInfo createTemplate() { - try { - DataStore store = createImageStore(); - VMTemplateVO image = createImageData(); - TemplateInfo template = imageDataFactory.getTemplate(image.getId(), store); - //AsyncCallFuture future = imageService.createTemplateAsync(template, store); - //future.get(); - template = imageDataFactory.getTemplate(image.getId(), store); - /*imageProviderMgr.configure("image Provider", new HashMap()); - VMTemplateVO image = createImageData(); - ImageDataStoreProvider defaultProvider = imageProviderMgr.getProvider("DefaultProvider"); - ImageDataStoreLifeCycle lifeCycle = defaultProvider.getLifeCycle(); - ImageDataStore store = lifeCycle.registerDataStore("defaultHttpStore", new HashMap()); - imageService.registerTemplate(image.getId(), store.getImageDataStoreId()); - TemplateEntity te = imageService.getTemplateEntity(image.getId()); - return te;*/ - return template; - } catch (Exception e) { - Assert.fail("failed", e); - return null; - } - } - - //@Test - public void createTemplateTest() { - createTemplate(); - } - - @Test - public void testCreatePrimaryStorage() { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); + @Test + public void testCreatePrimaryStorage() { + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); Map params = new HashMap(); URI uri = null; try { @@ -278,13 +285,13 @@ public class volumeServiceTest extends CloudStackTestNGBase { params.put("providerName", String.valueOf(provider.getName())); DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - this.primaryStore = lifeCycle.initialize(params); + this.primaryStore = lifeCycle.initialize(params); ClusterScope scope = new ClusterScope(clusterId, podId, dcId); lifeCycle.attachCluster(this.primaryStore, scope); - } + } - private DataStore createImageStore() { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider"); + private DataStore createImageStore() { + DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample image data store provider"); Map params = new HashMap(); String name = UUID.randomUUID().toString(); params.put("name", name); @@ -295,19 +302,20 @@ public class volumeServiceTest extends CloudStackTestNGBase { DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); DataStore store = lifeCycle.initialize(params); return store; - } - //@Test - public void testcreateImageStore() { - createImageStore(); - } + } + // @Test + public void testcreateImageStore() { + createImageStore(); + } - public DataStore createPrimaryDataStore() { - try { - DataStoreProvider provider = dataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); - Map params = new HashMap(); - URI uri = new URI(this.getPrimaryStorageUrl()); - params.put("url", this.getPrimaryStorageUrl()); + public DataStore createPrimaryDataStore() { + try { + DataStoreProvider provider = dataStoreProviderMgr + .getDataStoreProvider("sample primary data store provider"); + Map params = new HashMap(); + URI uri = new URI(this.getPrimaryStorageUrl()); + params.put("url", this.getPrimaryStorageUrl()); params.put("server", uri.getHost()); params.put("path", uri.getPath()); params.put("protocol", Storage.StoragePoolType.NetworkFilesystem); @@ -319,57 +327,58 @@ public class volumeServiceTest extends CloudStackTestNGBase { params.put("uuid", UUID.nameUUIDFromBytes(this.getPrimaryStorageUrl().getBytes()).toString()); params.put("providerName", String.valueOf(provider.getName())); - DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); - DataStore store = lifeCycle.initialize(params); - ClusterScope scope = new ClusterScope(clusterId, podId, dcId); - lifeCycle.attachCluster(store, scope); + DataStoreLifeCycle lifeCycle = provider.getDataStoreLifeCycle(); + DataStore store = lifeCycle.initialize(params); + ClusterScope scope = new ClusterScope(clusterId, podId, dcId); + lifeCycle.attachCluster(store, scope); - /* - PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("sample primary data store provider"); - primaryDataStoreProviderMgr.configure("primary data store mgr", new HashMap()); + /* + * PrimaryDataStoreProvider provider = + * primaryDataStoreProviderMgr.getDataStoreProvider + * ("sample primary data store provider"); + * primaryDataStoreProviderMgr.configure("primary data store mgr", + * new HashMap()); + * + * List ds = + * primaryStoreDao.findPoolByName(this.primaryName); if (ds.size() + * >= 1) { PrimaryDataStoreVO store = ds.get(0); if + * (store.getRemoved() == null) { return + * provider.getDataStore(store.getId()); } } + * + * + * Map params = new HashMap(); + * params.put("url", this.getPrimaryStorageUrl()); + * params.put("dcId", dcId.toString()); params.put("clusterId", + * clusterId.toString()); params.put("name", this.primaryName); + * PrimaryDataStoreInfo primaryDataStoreInfo = + * provider.registerDataStore(params); PrimaryDataStoreLifeCycle lc + * = primaryDataStoreInfo.getLifeCycle(); ClusterScope scope = new + * ClusterScope(clusterId, podId, dcId); lc.attachCluster(scope); + * return primaryDataStoreInfo; + */ + return store; + } catch (Exception e) { + return null; + } + } - List ds = primaryStoreDao.findPoolByName(this.primaryName); - if (ds.size() >= 1) { - PrimaryDataStoreVO store = ds.get(0); - if (store.getRemoved() == null) { - return provider.getDataStore(store.getId()); - } - } + private VolumeVO createVolume(Long templateId, long dataStoreId) { + VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); + volume.setPoolId(dataStoreId); + volume = volumeDao.persist(volume); + return volume; + } - - Map params = new HashMap(); - params.put("url", this.getPrimaryStorageUrl()); - params.put("dcId", dcId.toString()); - params.put("clusterId", clusterId.toString()); - params.put("name", this.primaryName); - PrimaryDataStoreInfo primaryDataStoreInfo = provider.registerDataStore(params); - PrimaryDataStoreLifeCycle lc = primaryDataStoreInfo.getLifeCycle(); - ClusterScope scope = new ClusterScope(clusterId, podId, dcId); - lc.attachCluster(scope); - return primaryDataStoreInfo; - */ - return store; - } catch (Exception e) { - return null; - } - } - - private VolumeVO createVolume(Long templateId, long dataStoreId) { - VolumeVO volume = new VolumeVO(Volume.Type.DATADISK, UUID.randomUUID().toString(), this.dcId, 1L, 1L, 1L, 1000); - volume.setPoolId(dataStoreId); - volume = volumeDao.persist(volume); - return volume; - } - - @Test(priority=2) - public void createVolumeFromTemplate() { - DataStore primaryStore = this.primaryStore; - TemplateInfo te = createTemplate(); - VolumeVO volume = createVolume(te.getId(), primaryStore.getId()); - VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore); - //ve.createVolumeFromTemplate(primaryStore.getId(), new VHD(), te); - AsyncCallFuture future = volumeService.createVolumeFromTemplateAsync(vol, primaryStore.getId(), te); - try { + @Test(priority = 2) + public void createVolumeFromTemplate() { + DataStore primaryStore = this.primaryStore; + TemplateInfo te = createTemplate(); + VolumeVO volume = createVolume(te.getId(), primaryStore.getId()); + VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore); + // ve.createVolumeFromTemplate(primaryStore.getId(), new VHD(), te); + AsyncCallFuture future = volumeService.createVolumeFromTemplateAsync(vol, + primaryStore.getId(), te); + try { future.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -378,15 +387,15 @@ public class volumeServiceTest extends CloudStackTestNGBase { // TODO Auto-generated catch block e.printStackTrace(); } - } + } - //@Test(priority=3) - public void createDataDisk() { - DataStore primaryStore = this.primaryStore; - VolumeVO volume = createVolume(null, primaryStore.getId()); - VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore); - AsyncCallFuture future = volumeService.createVolumeAsync(vol, primaryStore); - try { + // @Test(priority=3) + public void createDataDisk() { + DataStore primaryStore = this.primaryStore; + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore); + AsyncCallFuture future = volumeService.createVolumeAsync(vol, primaryStore); + try { future.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -395,28 +404,15 @@ public class volumeServiceTest extends CloudStackTestNGBase { // TODO Auto-generated catch block e.printStackTrace(); } - } + } - //@Test(priority=3) - public void createAndDeleteDataDisk() { - DataStore primaryStore = this.primaryStore; - VolumeVO volume = createVolume(null, primaryStore.getId()); - VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore); - AsyncCallFuture future = volumeService.createVolumeAsync(vol, primaryStore); - try { - future.get(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - //delete the volume - vol = volumeFactory.getVolume(volume.getId(), primaryStore); - future = volumeService.expungeVolumeAsync(vol); - try { + // @Test(priority=3) + public void createAndDeleteDataDisk() { + DataStore primaryStore = this.primaryStore; + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo vol = volumeFactory.getVolume(volume.getId(), primaryStore); + AsyncCallFuture future = volumeService.createVolumeAsync(vol, primaryStore); + try { future.get(); } catch (InterruptedException e) { // TODO Auto-generated catch block @@ -425,41 +421,53 @@ public class volumeServiceTest extends CloudStackTestNGBase { // TODO Auto-generated catch block e.printStackTrace(); } - } - //@Test(priority=3) - public void tearDown() { - List ds = primaryStoreDao.findPoolByName(this.primaryName); - for (int i = 0; i < ds.size(); i++) { - StoragePoolVO store = ds.get(i); - store.setUuid(null); - primaryStoreDao.remove(ds.get(i).getId()); - primaryStoreDao.expunge(ds.get(i).getId()); - } - } + // delete the volume + vol = volumeFactory.getVolume(volume.getId(), primaryStore); + future = volumeService.expungeVolumeAsync(vol); + try { + future.get(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (ExecutionException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } - //@Test - //@Test + // @Test(priority=3) + public void tearDown() { + List ds = primaryStoreDao.findPoolByName(this.primaryName); + for (int i = 0; i < ds.size(); i++) { + StoragePoolVO store = ds.get(i); + store.setUuid(null); + primaryStoreDao.remove(ds.get(i).getId()); + primaryStoreDao.expunge(ds.get(i).getId()); + } + } + + // @Test + // @Test public void test1() { - /*System.out.println(VolumeTypeHelper.getType("Root")); - System.out.println(VolumeDiskTypeHelper.getDiskType("vmdk")); - System.out.println(ImageFormatHelper.getFormat("ova")); - AssertJUnit.assertFalse(new VMDK().equals(new VHD())); - VMDK vmdk = new VMDK(); - AssertJUnit.assertTrue(vmdk.equals(vmdk)); - VMDK newvmdk = new VMDK(); - AssertJUnit.assertTrue(vmdk.equals(newvmdk)); - - ImageFormat ova = new OVA(); - ImageFormat iso = new ISO(); - AssertJUnit.assertTrue(ova.equals(new OVA())); - AssertJUnit.assertFalse(ova.equals(iso)); - AssertJUnit.assertTrue(ImageFormatHelper.getFormat("test").equals(new Unknown())); - - VolumeDiskType qcow2 = new QCOW2(); - ImageFormat qcow2format = new org.apache.cloudstack.storage.image.format.QCOW2(); - AssertJUnit.assertFalse(qcow2.equals(qcow2format)); -*/ - } + /* + * System.out.println(VolumeTypeHelper.getType("Root")); + * System.out.println(VolumeDiskTypeHelper.getDiskType("vmdk")); + * System.out.println(ImageFormatHelper.getFormat("ova")); + * AssertJUnit.assertFalse(new VMDK().equals(new VHD())); VMDK vmdk = + * new VMDK(); AssertJUnit.assertTrue(vmdk.equals(vmdk)); VMDK newvmdk = + * new VMDK(); AssertJUnit.assertTrue(vmdk.equals(newvmdk)); + * + * ImageFormat ova = new OVA(); ImageFormat iso = new ISO(); + * AssertJUnit.assertTrue(ova.equals(new OVA())); + * AssertJUnit.assertFalse(ova.equals(iso)); + * AssertJUnit.assertTrue(ImageFormatHelper.getFormat("test").equals(new + * Unknown())); + * + * VolumeDiskType qcow2 = new QCOW2(); ImageFormat qcow2format = new + * org.apache.cloudstack.storage.image.format.QCOW2(); + * AssertJUnit.assertFalse(qcow2.equals(qcow2format)); + */ + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java index c530e4a815e..aafdad05ff0 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotDataFactoryImpl.java @@ -26,18 +26,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; -import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; -import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.exception.CloudRuntimeException; @Component @@ -50,10 +45,11 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { DataStoreManager storeMgr; @Inject VolumeDataFactory volumeFactory; + @Override public SnapshotInfo getSnapshot(long snapshotId, DataStore store) { SnapshotVO snapshot = snapshotDao.findById(snapshotId); - SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); + SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); return so; } @@ -63,7 +59,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { if (snapshot == null) { throw new CloudRuntimeException("Can't find snapshot: " + obj.getId()); } - SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); + SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); return so; } @@ -75,7 +71,7 @@ public class SnapshotDataFactoryImpl implements SnapshotDataFactory { return null; } DataStore store = this.storeMgr.getDataStore(snapshotStore.getDataStoreId(), role); - SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); + SnapshotObject so = SnapshotObject.getSnapshotObject(snapshot, store); return so; } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 8b3c1f6c181..6aee3ea9503 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -91,7 +91,8 @@ public class SnapshotObject implements SnapshotInfo { @Override public SnapshotInfo getParent() { - SnapshotDataStoreVO snapStoreVO = this.snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), this.store.getId(), this.snapshot.getId()); + SnapshotDataStoreVO snapStoreVO = this.snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), + this.store.getId(), this.snapshot.getId()); if (snapStoreVO == null) { return null; } @@ -106,7 +107,8 @@ public class SnapshotObject implements SnapshotInfo { @Override public SnapshotInfo getChild() { - SearchCriteriaService sc = SearchCriteria2.create(SnapshotDataStoreVO.class); + SearchCriteriaService sc = SearchCriteria2 + .create(SnapshotDataStoreVO.class); sc.addAnd(sc.getEntity().getDataStoreId(), Op.EQ, this.store.getId()); sc.addAnd(sc.getEntity().getRole(), Op.EQ, this.store.getRole()); sc.addAnd(sc.getEntity().getParentSnapshotId(), Op.EQ, this.getId()); @@ -246,8 +248,8 @@ public class SnapshotObject implements SnapshotInfo { @Override public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { - SnapshotDataStoreVO snapshotStore = this.snapshotStoreDao.findByStoreSnapshot(this.getDataStore().getRole(), this.getDataStore().getId(), - this.getId()); + SnapshotDataStoreVO snapshotStore = this.snapshotStoreDao.findByStoreSnapshot( + this.getDataStore().getRole(), this.getDataStore().getId(), this.getId()); if (answer instanceof CreateObjectAnswer) { SnapshotObjectTO snapshotTO = (SnapshotObjectTO) ((CreateObjectAnswer) answer).getData(); snapshotStore.setInstallPath(snapshotTO.getPath()); diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 5717c179858..545a6a0ecef 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -17,7 +17,6 @@ package org.apache.cloudstack.storage.snapshot; -import java.util.List; import java.util.concurrent.ExecutionException; import javax.inject.Inject; @@ -25,19 +24,16 @@ import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; 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.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -51,10 +47,7 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.api.BackupSnapshotAnswer; -import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.dao.ClusterDao; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; @@ -70,391 +63,372 @@ import com.cloud.vm.snapshot.dao.VMSnapshotDao; @Component public class SnapshotServiceImpl implements SnapshotService { - private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class); - @Inject - protected VolumeDao _volsDao; - @Inject - protected UserVmDao _vmDao; - @Inject - protected PrimaryDataStoreDao _storagePoolDao; - @Inject - protected ClusterDao _clusterDao; - @Inject - protected SnapshotDao _snapshotDao; - @Inject - protected SnapshotDataStoreDao _snapshotStoreDao; + private static final Logger s_logger = Logger.getLogger(SnapshotServiceImpl.class); + @Inject + protected VolumeDao _volsDao; + @Inject + protected UserVmDao _vmDao; + @Inject + protected PrimaryDataStoreDao _storagePoolDao; + @Inject + protected ClusterDao _clusterDao; + @Inject + protected SnapshotDao _snapshotDao; + @Inject + protected SnapshotDataStoreDao _snapshotStoreDao; - @Inject - protected SnapshotManager snapshotMgr; - @Inject - protected VolumeManager volumeMgr; - @Inject - private ConfigurationDao _configDao; - @Inject - protected SnapshotStateMachineManager stateMachineManager; - @Inject - private VolumeDao volumeDao; - @Inject - SnapshotDataFactory snapshotfactory; - @Inject - DataStoreManager dataStoreMgr; - @Inject - DataMotionService motionSrv; - @Inject - ObjectInDataStoreManager objInStoreMgr; - @Inject - VMSnapshotDao _vmSnapshotDao; + @Inject + protected SnapshotManager snapshotMgr; + @Inject + protected VolumeManager volumeMgr; + @Inject + protected SnapshotStateMachineManager stateMachineManager; + @Inject + SnapshotDataFactory snapshotfactory; + @Inject + DataStoreManager dataStoreMgr; + @Inject + DataMotionService motionSrv; + @Inject + ObjectInDataStoreManager objInStoreMgr; + @Inject + VMSnapshotDao _vmSnapshotDao; + static private class CreateSnapshotContext extends AsyncRpcConext { + final SnapshotInfo snapshot; + final AsyncCallFuture future; + public CreateSnapshotContext(AsyncCompletionCallback callback, VolumeInfo volume, SnapshotInfo snapshot, + AsyncCallFuture future) { + super(callback); + this.snapshot = snapshot; + this.future = future; + } + } + static private class DeleteSnapshotContext extends AsyncRpcConext { + final SnapshotInfo snapshot; + final AsyncCallFuture future; - static private class CreateSnapshotContext extends AsyncRpcConext { - final VolumeInfo volume; - final SnapshotInfo snapshot; - final AsyncCallFuture future; - public CreateSnapshotContext(AsyncCompletionCallback callback, VolumeInfo volume, - SnapshotInfo snapshot, - AsyncCallFuture future) { - super(callback); - this.volume = volume; - this.snapshot = snapshot; - this.future = future; - } - } + public DeleteSnapshotContext(AsyncCompletionCallback callback, SnapshotInfo snapshot, + AsyncCallFuture future) { + super(callback); + this.snapshot = snapshot; + this.future = future; + } - static private class DeleteSnapshotContext extends AsyncRpcConext { - final SnapshotInfo snapshot; - final AsyncCallFuture future; - public DeleteSnapshotContext(AsyncCompletionCallback callback, SnapshotInfo snapshot, - AsyncCallFuture future) { - super(callback); - this.snapshot = snapshot; - this.future = future; - } + } - } + static private class CopySnapshotContext extends AsyncRpcConext { + final SnapshotInfo srcSnapshot; + final SnapshotInfo destSnapshot; + final AsyncCallFuture future; - static private class CopySnapshotContext extends AsyncRpcConext { - final SnapshotInfo srcSnapshot; - final SnapshotInfo destSnapshot; - final AsyncCallFuture future; - public CopySnapshotContext(AsyncCompletionCallback callback, - SnapshotInfo srcSnapshot, - SnapshotInfo destSnapshot, - AsyncCallFuture future) { - super(callback); - this.srcSnapshot = srcSnapshot; - this.destSnapshot = destSnapshot; - this.future = future; - } + public CopySnapshotContext(AsyncCompletionCallback callback, SnapshotInfo srcSnapshot, + SnapshotInfo destSnapshot, AsyncCallFuture future) { + super(callback); + this.srcSnapshot = srcSnapshot; + this.destSnapshot = destSnapshot; + this.future = future; + } - } + } - protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher callback, - CreateSnapshotContext context) { - CreateCmdResult result = callback.getResult(); - SnapshotObject snapshot = (SnapshotObject)context.snapshot; - AsyncCallFuture future = context.future; - SnapshotResult snapResult = new SnapshotResult(snapshot, result.getAnswer()); - if (result.isFailed()) { - s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult()); - try { - snapshot.processEvent(Snapshot.Event.OperationFailed); - snapshot.processEvent(Event.OperationFailed); - } catch (Exception e) { - s_logger.debug("Failed to update snapshot state due to " + e.getMessage()); - } + protected Void createSnapshotAsyncCallback(AsyncCallbackDispatcher callback, + CreateSnapshotContext context) { + CreateCmdResult result = callback.getResult(); + SnapshotObject snapshot = (SnapshotObject) context.snapshot; + AsyncCallFuture future = context.future; + SnapshotResult snapResult = new SnapshotResult(snapshot, result.getAnswer()); + if (result.isFailed()) { + s_logger.debug("create snapshot " + context.snapshot.getName() + " failed: " + result.getResult()); + try { + snapshot.processEvent(Snapshot.Event.OperationFailed); + snapshot.processEvent(Event.OperationFailed); + } catch (Exception e) { + s_logger.debug("Failed to update snapshot state due to " + e.getMessage()); + } - snapResult.setResult(result.getResult()); - future.complete(snapResult); - return null; - } + snapResult.setResult(result.getResult()); + future.complete(snapResult); + return null; + } - try { - snapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); - snapshot.processEvent(Snapshot.Event.OperationSucceeded); - } catch (Exception e) { - s_logger.debug("Failed to create snapshot: ", e); - snapResult.setResult(e.toString()); - try { + try { + snapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); + snapshot.processEvent(Snapshot.Event.OperationSucceeded); + } catch (Exception e) { + s_logger.debug("Failed to create snapshot: ", e); + snapResult.setResult(e.toString()); + try { snapshot.processEvent(Snapshot.Event.OperationFailed); } catch (NoTransitionException e1) { s_logger.debug("Failed to change snapshot state: " + e1.toString()); } - } + } - future.complete(snapResult); - return null; - } + future.complete(snapResult); + return null; + } + @Override + public SnapshotResult takeSnapshot(SnapshotInfo snap) { + SnapshotObject snapshot = (SnapshotObject) snap; + SnapshotObject snapshotOnPrimary = null; + try { + snapshotOnPrimary = (SnapshotObject) snap.getDataStore().create(snapshot); + } catch (Exception e) { + s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage()); + throw new CloudRuntimeException(e); + } - @Override - public SnapshotResult takeSnapshot(SnapshotInfo snap) { - SnapshotObject snapshot = (SnapshotObject)snap; + try { + snapshotOnPrimary.processEvent(Snapshot.Event.CreateRequested); + } catch (NoTransitionException e) { + s_logger.debug("Failed to change snapshot state: " + e.toString()); + throw new CloudRuntimeException(e); + } - SnapshotObject snapshotOnPrimary = null; - try { - snapshotOnPrimary = (SnapshotObject)snap.getDataStore().create(snapshot); - } catch(Exception e) { - s_logger.debug("Failed to create snapshot state on data store due to " + e.getMessage()); - throw new CloudRuntimeException(e); - } + try { + snapshotOnPrimary.processEvent(Event.CreateOnlyRequested); + } catch (Exception e) { + s_logger.debug("Failed to change snapshot state: " + e.toString()); + try { + snapshotOnPrimary.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e1) { + s_logger.debug("Failed to change snapshot state: " + e1.toString()); + } + throw new CloudRuntimeException(e); + } - try { - snapshotOnPrimary.processEvent(Snapshot.Event.CreateRequested); - } catch (NoTransitionException e) { - s_logger.debug("Failed to change snapshot state: " + e.toString()); - throw new CloudRuntimeException(e); - } - - try { - snapshotOnPrimary.processEvent(Event.CreateOnlyRequested); - } catch (Exception e) { - s_logger.debug("Failed to change snapshot state: " + e.toString()); - try { - snapshotOnPrimary.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException e1) { - s_logger.debug("Failed to change snapshot state: " + e1.toString()); - } - throw new CloudRuntimeException(e); - } - - AsyncCallFuture future = new AsyncCallFuture(); - try { - CreateSnapshotContext context = new CreateSnapshotContext( - null, snap.getBaseVolume(), snapshotOnPrimary, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().createSnapshotAsyncCallback(null, null)) - .setContext(context); - PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver)snapshotOnPrimary.getDataStore().getDriver(); - primaryStore.takeSnapshot(snapshot, caller); - } catch (Exception e) { - s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); - try { + AsyncCallFuture future = new AsyncCallFuture(); + try { + CreateSnapshotContext context = new CreateSnapshotContext(null, + snap.getBaseVolume(), snapshotOnPrimary, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createSnapshotAsyncCallback(null, null)).setContext(context); + PrimaryDataStoreDriver primaryStore = (PrimaryDataStoreDriver) snapshotOnPrimary.getDataStore().getDriver(); + primaryStore.takeSnapshot(snapshot, caller); + } catch (Exception e) { + s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); + try { snapshot.processEvent(Snapshot.Event.OperationFailed); } catch (NoTransitionException e1) { - s_logger.debug("Failed to change state for event: OperationFailed" , e); + s_logger.debug("Failed to change state for event: OperationFailed", e); } - throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId()); - } + throw new CloudRuntimeException("Failed to take snapshot" + snapshot.getId()); + } - SnapshotResult result; + SnapshotResult result; - try { - result = future.get(); - if (result.isFailed()) { - s_logger.debug("Failed to create snapshot:" + result.getResult()); - throw new CloudRuntimeException(result.getResult()); - } - return result; - } catch (InterruptedException e) { - s_logger.debug("Failed to create snapshot", e); - throw new CloudRuntimeException("Failed to create snapshot", e); - } catch (ExecutionException e) { - s_logger.debug("Failed to create snapshot", e); - throw new CloudRuntimeException("Failed to create snapshot", e); - } + try { + result = future.get(); + if (result.isFailed()) { + s_logger.debug("Failed to create snapshot:" + result.getResult()); + throw new CloudRuntimeException(result.getResult()); + } + return result; + } catch (InterruptedException e) { + s_logger.debug("Failed to create snapshot", e); + throw new CloudRuntimeException("Failed to create snapshot", e); + } catch (ExecutionException e) { + s_logger.debug("Failed to create snapshot", e); + throw new CloudRuntimeException("Failed to create snapshot", e); + } - } + } - // if a snapshot has parent snapshot, the new snapshot should be stored in the same store as its parent since - // we are taking delta snapshot - private DataStore findSnapshotImageStore(SnapshotInfo snapshot){ - if ( snapshot.getParent() == null ){ - return dataStoreMgr.getImageStore(snapshot.getDataCenterId()); - } else{ - SnapshotInfo parentSnapshot = snapshot.getParent(); - // Note that DataStore information in parentSnapshot is for primary data store here, we need to - // find the image store where the parent snapshot backup is located - SnapshotDataStoreVO parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); - return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), - parentSnapshotOnBackupStore.getRole()); - } - } + // if a snapshot has parent snapshot, the new snapshot should be stored in + // the same store as its parent since + // we are taking delta snapshot + private DataStore findSnapshotImageStore(SnapshotInfo snapshot) { + if (snapshot.getParent() == null) { + return dataStoreMgr.getImageStore(snapshot.getDataCenterId()); + } else { + SnapshotInfo parentSnapshot = snapshot.getParent(); + // Note that DataStore information in parentSnapshot is for primary + // data store here, we need to + // find the image store where the parent snapshot backup is located + SnapshotDataStoreVO parentSnapshotOnBackupStore = _snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), + DataStoreRole.Image); + return dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), + parentSnapshotOnBackupStore.getRole()); + } + } + @Override + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { + SnapshotObject snapObj = (SnapshotObject) snapshot; + AsyncCallFuture future = new AsyncCallFuture(); + SnapshotResult result = new SnapshotResult(snapshot, null); + try { - @Override - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { - SnapshotObject snapObj = (SnapshotObject)snapshot; - AsyncCallFuture future = new AsyncCallFuture(); - SnapshotResult result = new SnapshotResult(snapshot, null); - try { + snapObj.processEvent(Snapshot.Event.BackupToSecondary); - snapObj.processEvent(Snapshot.Event.BackupToSecondary); + DataStore imageStore = this.findSnapshotImageStore(snapshot); + if (imageStore == null) { + throw new CloudRuntimeException("can not find an image stores"); + } - DataStore imageStore = this.findSnapshotImageStore(snapshot); - if (imageStore == null) { - throw new CloudRuntimeException("can not find an image stores"); - } + SnapshotInfo snapshotOnImageStore = (SnapshotInfo) imageStore.create(snapshot); - SnapshotInfo snapshotOnImageStore = (SnapshotInfo)imageStore.create(snapshot); - - snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); - CopySnapshotContext context = new CopySnapshotContext(null, snapshot, - snapshotOnImageStore, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().copySnapshotAsyncCallback(null, null)) - .setContext(context); - this.motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller); - } catch (Exception e) { - s_logger.debug("Failed to copy snapshot", e); - result.setResult("Failed to copy snapshot:" +e.toString()); - try { + snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); + CopySnapshotContext context = new CopySnapshotContext(null, snapshot, + snapshotOnImageStore, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setCallback(caller.getTarget().copySnapshotAsyncCallback(null, null)).setContext(context); + this.motionSrv.copyAsync(snapshot, snapshotOnImageStore, caller); + } catch (Exception e) { + s_logger.debug("Failed to copy snapshot", e); + result.setResult("Failed to copy snapshot:" + e.toString()); + try { snapObj.processEvent(Snapshot.Event.OperationFailed); } catch (NoTransitionException e1) { s_logger.debug("Failed to change state: " + e1.toString()); } - future.complete(result); - } + future.complete(result); + } - try { - SnapshotResult res = future.get(); - if (res.isFailed()) { - throw new CloudRuntimeException(res.getResult()); - } - SnapshotInfo destSnapshot = res.getSnashot(); - return destSnapshot; - } catch (InterruptedException e) { - s_logger.debug("failed copy snapshot", e); - throw new CloudRuntimeException("Failed to copy snapshot" , e); - } catch (ExecutionException e) { - s_logger.debug("Failed to copy snapshot", e); - throw new CloudRuntimeException("Failed to copy snapshot" , e); - } + try { + SnapshotResult res = future.get(); + if (res.isFailed()) { + throw new CloudRuntimeException(res.getResult()); + } + SnapshotInfo destSnapshot = res.getSnashot(); + return destSnapshot; + } catch (InterruptedException e) { + s_logger.debug("failed copy snapshot", e); + throw new CloudRuntimeException("Failed to copy snapshot", e); + } catch (ExecutionException e) { + s_logger.debug("Failed to copy snapshot", e); + throw new CloudRuntimeException("Failed to copy snapshot", e); + } - } + } - protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher callback, - CopySnapshotContext context) { - CopyCommandResult result = callback.getResult(); - SnapshotInfo destSnapshot = context.destSnapshot; - SnapshotObject srcSnapshot = (SnapshotObject)context.srcSnapshot; - AsyncCallFuture future = context.future; - SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer()); - if (result.isFailed()) { - try { - destSnapshot.processEvent(Event.OperationFailed); - srcSnapshot.processEvent(Snapshot.Event.OperationFailed); - } catch (NoTransitionException e) { - s_logger.debug("Failed to update state: " + e.toString()); - } - snapResult.setResult(result.getResult()); - future.complete(snapResult); - return null; - } + protected Void copySnapshotAsyncCallback(AsyncCallbackDispatcher callback, + CopySnapshotContext context) { + CopyCommandResult result = callback.getResult(); + SnapshotInfo destSnapshot = context.destSnapshot; + SnapshotObject srcSnapshot = (SnapshotObject) context.srcSnapshot; + AsyncCallFuture future = context.future; + SnapshotResult snapResult = new SnapshotResult(destSnapshot, result.getAnswer()); + if (result.isFailed()) { + try { + destSnapshot.processEvent(Event.OperationFailed); + srcSnapshot.processEvent(Snapshot.Event.OperationFailed); + } catch (NoTransitionException e) { + s_logger.debug("Failed to update state: " + e.toString()); + } + snapResult.setResult(result.getResult()); + future.complete(snapResult); + return null; + } - try { - CopyCmdAnswer answer = (CopyCmdAnswer)result.getAnswer(); - destSnapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); - srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); - snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId(), destSnapshot.getDataStore()), answer); - future.complete(snapResult); - } catch (Exception e) { - s_logger.debug("Failed to update snapshot state", e); - snapResult.setResult(e.toString()); - future.complete(snapResult); - } - return null; - } + try { + CopyCmdAnswer answer = (CopyCmdAnswer) result.getAnswer(); + destSnapshot.processEvent(Event.OperationSuccessed, result.getAnswer()); + srcSnapshot.processEvent(Snapshot.Event.OperationSucceeded); + snapResult = new SnapshotResult(this.snapshotfactory.getSnapshot(destSnapshot.getId(), + destSnapshot.getDataStore()), answer); + future.complete(snapResult); + } catch (Exception e) { + s_logger.debug("Failed to update snapshot state", e); + snapResult.setResult(e.toString()); + future.complete(snapResult); + } + return null; + } - @DB - protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { - SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao.findBySnapshot(snapshot.getId(), DataStoreRole.Image); - if ( snapshotStore == null ){ + @DB + protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { + SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao + .findBySnapshot(snapshot.getId(), DataStoreRole.Image); + if (snapshotStore == null) { s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); return false; - } - DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); - if (store == null) { - s_logger.debug("Can't find mage store " + snapshotStore.getDataStoreId()); - return false; - } + } + DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); + if (store == null) { + s_logger.debug("Can't find mage store " + snapshotStore.getDataStoreId()); + return false; + } - try { - SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store); - snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + try { + SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store); + snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); - AsyncCallFuture future = new AsyncCallFuture(); - DeleteSnapshotContext context = new DeleteSnapshotContext(null, - snapshotInfo, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().deleteSnapshotCallback(null, null)) - .setContext(context); + AsyncCallFuture future = new AsyncCallFuture(); + DeleteSnapshotContext context = new DeleteSnapshotContext(null, snapshotInfo, + future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().deleteSnapshotCallback(null, null)).setContext(context); - store.getDriver().deleteAsync(snapshotInfo, caller); + store.getDriver().deleteAsync(snapshotInfo, caller); - SnapshotResult result = future.get(); - if (result.isFailed()) { - s_logger.debug("Failed to delete snapsoht: " + result.getResult()); - } - return result.isSuccess(); - } catch (Exception e) { - s_logger.debug("Failed to delete snapshot", e); - return false; - } - } + SnapshotResult result = future.get(); + if (result.isFailed()) { + s_logger.debug("Failed to delete snapsoht: " + result.getResult()); + } + return result.isSuccess(); + } catch (Exception e) { + s_logger.debug("Failed to delete snapshot", e); + return false; + } + } - protected Void deleteSnapshotCallback(AsyncCallbackDispatcher callback, - DeleteSnapshotContext context) { - CommandResult result = callback.getResult(); - AsyncCallFuture future = context.future; - SnapshotInfo snapshot = context.snapshot; - if (result.isFailed()) { - s_logger.debug("delete snapshot failed" + result.getResult()); - snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); - SnapshotResult res = new SnapshotResult(context.snapshot, null); - future.complete(res); - return null; - } - snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); - SnapshotResult res = new SnapshotResult(context.snapshot, null); - future.complete(res); - return null; - } + protected Void deleteSnapshotCallback(AsyncCallbackDispatcher callback, + DeleteSnapshotContext context) { + CommandResult result = callback.getResult(); + AsyncCallFuture future = context.future; + SnapshotInfo snapshot = context.snapshot; + if (result.isFailed()) { + s_logger.debug("delete snapshot failed" + result.getResult()); + snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed); + SnapshotResult res = new SnapshotResult(context.snapshot, null); + future.complete(res); + return null; + } + snapshot.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed); + SnapshotResult res = new SnapshotResult(context.snapshot, null); + future.complete(res); + return null; + } - @Override - public boolean deleteSnapshot(SnapshotInfo snapInfo) { - snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); + @Override + public boolean deleteSnapshot(SnapshotInfo snapInfo) { + snapInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); - AsyncCallFuture future = new AsyncCallFuture(); - DeleteSnapshotContext context = new DeleteSnapshotContext(null, - snapInfo, future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().deleteSnapshotCallback(null, null)) - .setContext(context); - DataStore store = snapInfo.getDataStore(); - store.getDriver().deleteAsync(snapInfo, caller); + AsyncCallFuture future = new AsyncCallFuture(); + DeleteSnapshotContext context = new DeleteSnapshotContext(null, snapInfo, future); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().deleteSnapshotCallback(null, null)).setContext(context); + DataStore store = snapInfo.getDataStore(); + store.getDriver().deleteAsync(snapInfo, caller); - SnapshotResult result = null; - try { - result = future.get(); - if (result.isFailed()) { - throw new CloudRuntimeException(result.getResult()); - } - return true; - } catch (InterruptedException e) { - s_logger.debug("delete snapshot is failed: " + e.toString()); - } catch (ExecutionException e) { - s_logger.debug("delete snapshot is failed: " + e.toString()); - } + SnapshotResult result = null; + try { + result = future.get(); + if (result.isFailed()) { + throw new CloudRuntimeException(result.getResult()); + } + return true; + } catch (InterruptedException e) { + s_logger.debug("delete snapshot is failed: " + e.toString()); + } catch (ExecutionException e) { + s_logger.debug("delete snapshot is failed: " + e.toString()); + } - return false; + return false; - } + } - @Override - public boolean revertSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub - return false; - } + @Override + public boolean revertSnapshot(SnapshotInfo snapshot) { + // TODO Auto-generated method stub + return false; + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java index c6057704cd8..f07db7ed9a0 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java @@ -22,5 +22,5 @@ import com.cloud.storage.SnapshotVO; import com.cloud.utils.fsm.NoTransitionException; public interface SnapshotStateMachineManager { - public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException; + public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException; } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java index 489ba280e7d..c756ddb4876 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManagerImpl.java @@ -31,30 +31,31 @@ import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; @Component -public class SnapshotStateMachineManagerImpl implements -SnapshotStateMachineManager { - private StateMachine2 stateMachine = new StateMachine2(); +public class SnapshotStateMachineManagerImpl implements SnapshotStateMachineManager { + private StateMachine2 stateMachine = new StateMachine2(); @Inject - protected SnapshotDao snapshotDao; - public SnapshotStateMachineManagerImpl() { - stateMachine.addTransition(Snapshot.State.Allocated, Event.CreateRequested, Snapshot.State.Creating); - stateMachine.addTransition(Snapshot.State.Creating, Event.OperationSucceeded, Snapshot.State.CreatedOnPrimary); - stateMachine.addTransition(Snapshot.State.Creating, Event.OperationNotPerformed, Snapshot.State.BackedUp); - stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error); - stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp); - stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp); - stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.CreatedOnPrimary); - stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying); - stateMachine.addTransition(Snapshot.State.BackedUp, Event.CopyingRequested, Snapshot.State.Copying); - stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp); - stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp); - stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed); - stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, Snapshot.State.Error); - - stateMachine.registerListener(new SnapshotStateListener()); - } - - public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException { - stateMachine.transitTo(snapshot, event, null, snapshotDao); - } -} + protected SnapshotDao snapshotDao; + + public SnapshotStateMachineManagerImpl() { + stateMachine.addTransition(Snapshot.State.Allocated, Event.CreateRequested, Snapshot.State.Creating); + stateMachine.addTransition(Snapshot.State.Creating, Event.OperationSucceeded, Snapshot.State.CreatedOnPrimary); + stateMachine.addTransition(Snapshot.State.Creating, Event.OperationNotPerformed, Snapshot.State.BackedUp); + stateMachine.addTransition(Snapshot.State.Creating, Event.OperationFailed, Snapshot.State.Error); + stateMachine.addTransition(Snapshot.State.CreatedOnPrimary, Event.BackupToSecondary, Snapshot.State.BackingUp); + stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationSucceeded, Snapshot.State.BackedUp); + stateMachine.addTransition(Snapshot.State.BackingUp, Event.OperationFailed, Snapshot.State.CreatedOnPrimary); + stateMachine.addTransition(Snapshot.State.BackedUp, Event.DestroyRequested, Snapshot.State.Destroying); + stateMachine.addTransition(Snapshot.State.BackedUp, Event.CopyingRequested, Snapshot.State.Copying); + stateMachine.addTransition(Snapshot.State.Copying, Event.OperationSucceeded, Snapshot.State.BackedUp); + stateMachine.addTransition(Snapshot.State.Copying, Event.OperationFailed, Snapshot.State.BackedUp); + stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationSucceeded, Snapshot.State.Destroyed); + stateMachine.addTransition(Snapshot.State.Destroying, Event.OperationFailed, Snapshot.State.Error); + + stateMachine.registerListener(new SnapshotStateListener()); + } + + @Override + public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException { + stateMachine.transitTo(snapshot, event, null, snapshotDao); + } +} diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java index 5e78b017fbb..1b579227f84 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStrategyBase.java @@ -23,16 +23,16 @@ import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotStrategy; public abstract class SnapshotStrategyBase implements SnapshotStrategy { - @Inject - SnapshotService snapshotSvr; + @Inject + SnapshotService snapshotSvr; - @Override - public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { - return snapshotSvr.takeSnapshot(snapshot).getSnashot(); - } + @Override + public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { + return snapshotSvr.takeSnapshot(snapshot).getSnashot(); + } - @Override - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { - return snapshotSvr.backupSnapshot(snapshot); - } + @Override + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { + return snapshotSvr.backupSnapshot(snapshot); + } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 32504eeaed5..0c3f31c9ef8 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -16,18 +16,14 @@ // under the License. package org.apache.cloudstack.storage.snapshot; -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.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult; -import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; @@ -38,11 +34,9 @@ import org.springframework.stereotype.Component; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.utils.NumbersUtil; @@ -51,165 +45,161 @@ import com.cloud.utils.fsm.NoTransitionException; @Component public class XenserverSnapshotStrategy extends SnapshotStrategyBase { - private static final Logger s_logger = Logger - .getLogger(XenserverSnapshotStrategy.class); + private static final Logger s_logger = Logger.getLogger(XenserverSnapshotStrategy.class); - @Inject - SnapshotManager snapshotMgr; - @Inject - SnapshotService snapshotSvr; - @Inject - DataStoreManager dataStoreMgr; - @Inject - SnapshotDataStoreDao snapshotStoreDao; - @Inject - ConfigurationDao configDao; - @Inject - SnapshotDao snapshotDao; - @Inject - SnapshotDataFactory snapshotDataFactory; + @Inject + SnapshotManager snapshotMgr; + @Inject + SnapshotService snapshotSvr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + SnapshotDataStoreDao snapshotStoreDao; + @Inject + ConfigurationDao configDao; + @Inject + SnapshotDao snapshotDao; + @Inject + SnapshotDataFactory snapshotDataFactory; - @Override - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { - SnapshotInfo parentSnapshot = snapshot.getParent(); - if (parentSnapshot != null && parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) { - s_logger.debug("backup an empty snapshot"); - //don't need to backup this snapshot - SnapshotDataStoreVO parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); - if (parentSnapshotOnBackupStore != null && - parentSnapshotOnBackupStore.getState() == State.Ready) { - DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), - parentSnapshotOnBackupStore.getRole()); + @Override + public SnapshotInfo backupSnapshot(SnapshotInfo snapshot) { + SnapshotInfo parentSnapshot = snapshot.getParent(); + if (parentSnapshot != null && parentSnapshot.getPath().equalsIgnoreCase(snapshot.getPath())) { + s_logger.debug("backup an empty snapshot"); + // don't need to backup this snapshot + SnapshotDataStoreVO parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot( + parentSnapshot.getId(), DataStoreRole.Image); + if (parentSnapshotOnBackupStore != null && parentSnapshotOnBackupStore.getState() == State.Ready) { + DataStore store = dataStoreMgr.getDataStore(parentSnapshotOnBackupStore.getDataStoreId(), + parentSnapshotOnBackupStore.getRole()); - SnapshotInfo snapshotOnImageStore = (SnapshotInfo)store.create(snapshot); - snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); + SnapshotInfo snapshotOnImageStore = (SnapshotInfo) store.create(snapshot); + snapshotOnImageStore.processEvent(Event.CreateOnlyRequested); - SnapshotObjectTO snapTO = new SnapshotObjectTO(); - snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath()); - CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO); + SnapshotObjectTO snapTO = new SnapshotObjectTO(); + snapTO.setPath(parentSnapshotOnBackupStore.getInstallPath()); + CreateObjectAnswer createSnapshotAnswer = new CreateObjectAnswer(snapTO); - snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer); - SnapshotObject snapObj = (SnapshotObject)snapshot; - try { - snapObj.processEvent(Snapshot.Event.OperationNotPerformed); - } catch (NoTransitionException e) { - s_logger.debug("Failed to change state: " + snapshot.getId() + ": " +e.toString()); - throw new CloudRuntimeException(e.toString()); - } - return this.snapshotDataFactory.getSnapshot(snapObj.getId(), store); - } else { - s_logger.debug("parent snapshot hasn't been backed up yet"); - } - } + snapshotOnImageStore.processEvent(Event.OperationSuccessed, createSnapshotAnswer); + SnapshotObject snapObj = (SnapshotObject) snapshot; + try { + snapObj.processEvent(Snapshot.Event.OperationNotPerformed); + } catch (NoTransitionException e) { + s_logger.debug("Failed to change state: " + snapshot.getId() + ": " + e.toString()); + throw new CloudRuntimeException(e.toString()); + } + return this.snapshotDataFactory.getSnapshot(snapObj.getId(), store); + } else { + s_logger.debug("parent snapshot hasn't been backed up yet"); + } + } - //determine full snapshot backup or not + // determine full snapshot backup or not - boolean fullBackup = false; - long preSnapshotId = 0; - if (parentSnapshot != null) { + boolean fullBackup = false; - preSnapshotId = parentSnapshot.getId(); - int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), SnapshotManager.DELTAMAX); - int deltaSnap = _deltaSnapshotMax; + if (parentSnapshot != null) { + int _deltaSnapshotMax = NumbersUtil.parseInt(configDao.getValue("snapshot.delta.max"), + SnapshotManager.DELTAMAX); + int deltaSnap = _deltaSnapshotMax; - int i; - SnapshotDataStoreVO parentSnapshotOnBackupStore = null; - for (i = 1; i < deltaSnap; i++) { - parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), DataStoreRole.Image); + int i; + SnapshotDataStoreVO parentSnapshotOnBackupStore = null; + for (i = 1; i < deltaSnap; i++) { + parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(parentSnapshot.getId(), + DataStoreRole.Image); - Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId(); + Long prevBackupId = parentSnapshotOnBackupStore.getParentSnapshotId(); - if (prevBackupId == 0) { - break; - } + if (prevBackupId == 0) { + break; + } - parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image); - } - if (i >= deltaSnap) { - fullBackup = true; - } - } - - snapshot.addPayload(fullBackup); - return this.snapshotSvr.backupSnapshot(snapshot); - } - - protected void deleteSnapshotChain(SnapshotInfo snapshot) { - while(snapshot != null) { - SnapshotInfo child = snapshot.getChild(); - SnapshotInfo parent = snapshot.getParent(); - if (child == null) { - if (parent == null || !parent.getPath().equalsIgnoreCase(snapshot.getPath())) { - this.snapshotSvr.deleteSnapshot(snapshot); - snapshot = parent; - continue; - } - break; - } else { - break; - } - } - } + parentSnapshotOnBackupStore = this.snapshotStoreDao.findBySnapshot(prevBackupId, DataStoreRole.Image); + } + if (i >= deltaSnap) { + fullBackup = true; + } + } - @Override - public boolean deleteSnapshot(Long snapshotId) { - SnapshotVO snapshotVO = snapshotDao.findById(snapshotId); - if (snapshotVO.getState() == Snapshot.State.Destroyed) { - return true; - } - - if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) { - throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + " due to it is not in BackedUp Status"); - } + snapshot.addPayload(fullBackup); + return this.snapshotSvr.backupSnapshot(snapshot); + } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); - } - - - //firt mark the snapshot as destroyed, so that ui can't see it, but we may not destroy the snapshot on the storage, as other snaphosts may depend on it. - SnapshotInfo snapshotOnPrimary = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary); - SnapshotObject obj = (SnapshotObject)snapshotOnPrimary; - try { + protected void deleteSnapshotChain(SnapshotInfo snapshot) { + while (snapshot != null) { + SnapshotInfo child = snapshot.getChild(); + SnapshotInfo parent = snapshot.getParent(); + if (child == null) { + if (parent == null || !parent.getPath().equalsIgnoreCase(snapshot.getPath())) { + this.snapshotSvr.deleteSnapshot(snapshot); + snapshot = parent; + continue; + } + break; + } else { + break; + } + } + } + + @Override + public boolean deleteSnapshot(Long snapshotId) { + SnapshotVO snapshotVO = snapshotDao.findById(snapshotId); + if (snapshotVO.getState() == Snapshot.State.Destroyed) { + return true; + } + + if (!Snapshot.State.BackedUp.equals(snapshotVO.getState())) { + throw new InvalidParameterValueException("Can't delete snapshotshot " + snapshotId + + " due to it is not in BackedUp Status"); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Calling deleteSnapshot for snapshotId: " + snapshotId); + } + + // firt mark the snapshot as destroyed, so that ui can't see it, but we + // may not destroy the snapshot on the storage, as other snaphosts may + // depend on it. + SnapshotInfo snapshotOnPrimary = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Primary); + SnapshotObject obj = (SnapshotObject) snapshotOnPrimary; + try { obj.processEvent(Snapshot.Event.DestroyRequested); } catch (NoTransitionException e) { s_logger.debug("Failed to destroy snapshot: " + e.toString()); return false; } - - try { - /* - if (snapshotOnPrimary != null) { - deleteSnapshotChain(snapshotOnPrimary); - }*/ - SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image); - if (snapshotOnImage != null) { - deleteSnapshotChain(snapshotOnImage); - } - - obj.processEvent(Snapshot.Event.OperationSucceeded); - } catch (Exception e) { - s_logger.debug("Failed to delete snapshot: " + e.toString()); - try { + try { + SnapshotInfo snapshotOnImage = this.snapshotDataFactory.getSnapshot(snapshotId, DataStoreRole.Image); + if (snapshotOnImage != null) { + deleteSnapshotChain(snapshotOnImage); + } + + obj.processEvent(Snapshot.Event.OperationSucceeded); + } catch (Exception e) { + s_logger.debug("Failed to delete snapshot: " + e.toString()); + try { obj.processEvent(Snapshot.Event.OperationFailed); } catch (NoTransitionException e1) { s_logger.debug("Failed to change snapshot state: " + e.toString()); } - } - - return true; - } - - @Override - public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { - snapshot = snapshotSvr.takeSnapshot(snapshot).getSnashot(); - //TODO: add async - return this.backupSnapshot(snapshot); - } + } + + return true; + } + + @Override + public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { + snapshot = snapshotSvr.takeSnapshot(snapshot).getSnashot(); + // TODO: add async + return this.backupSnapshot(snapshot); + } @Override public boolean canHandle(Snapshot snapshot) { - return true; + return true; } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java index b05b803623f..43ec6097cac 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java @@ -35,87 +35,88 @@ import com.cloud.utils.db.GenericDao; import com.google.gson.annotations.Expose; @Entity -@Table(name="snapshots") +@Table(name = "snapshots") public class SnapshotVO { @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) - @Column(name="id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") private final long id = -1; - @Column(name="data_center_id") + @Column(name = "data_center_id") long dataCenterId; - @Column(name="account_id") + @Column(name = "account_id") long accountId; - @Column(name="domain_id") + @Column(name = "domain_id") long domainId; - @Column(name="volume_id") + @Column(name = "volume_id") Long volumeId; - @Column(name="disk_offering_id") + @Column(name = "disk_offering_id") Long diskOfferingId; @Expose - @Column(name="path") + @Column(name = "path") String path; @Expose - @Column(name="name") + @Column(name = "name") String name; @Expose - @Column(name="status", updatable = true, nullable=false) - @Enumerated(value=EnumType.STRING) + @Column(name = "status", updatable = true, nullable = false) + @Enumerated(value = EnumType.STRING) private State status; - @Column(name="snapshot_type") + @Column(name = "snapshot_type") short snapshotType; - @Column(name="type_description") + @Column(name = "type_description") String typeDescription; - @Column(name="size") + @Column(name = "size") long size; - @Column(name=GenericDao.CREATED_COLUMN) + @Column(name = GenericDao.CREATED_COLUMN) Date created; - @Column(name=GenericDao.REMOVED_COLUMN) + @Column(name = GenericDao.REMOVED_COLUMN) Date removed; - @Column(name="backup_snap_id") + @Column(name = "backup_snap_id") String backupSnapshotId; - @Column(name="swift_id") + @Column(name = "swift_id") Long swiftId; - @Column(name="s3_id") + @Column(name = "s3_id") Long s3Id; - @Column(name="sechost_id") + @Column(name = "sechost_id") Long secHostId; - @Column(name="prev_snap_id") + @Column(name = "prev_snap_id") long prevSnapshotId; - @Column(name="hypervisor_type") - @Enumerated(value=EnumType.STRING) - HypervisorType hypervisorType; + @Column(name = "hypervisor_type") + @Enumerated(value = EnumType.STRING) + HypervisorType hypervisorType; @Expose - @Column(name="version") + @Column(name = "version") String version; - @Column(name="uuid") + @Column(name = "uuid") String uuid; public SnapshotVO() { this.uuid = UUID.randomUUID().toString(); } - public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType ) { + public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, + String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType) { this.dataCenterId = dcId; this.accountId = accountId; this.domainId = domainId; @@ -141,16 +142,14 @@ public class SnapshotVO { return dataCenterId; } - public long getAccountId() { return accountId; } - public long getDomainId() { return domainId; } - + public long getVolumeId() { return volumeId; } @@ -210,8 +209,8 @@ public class SnapshotVO { this.snapshotType = snapshotType; } - public boolean isRecursive(){ - if ( snapshotType >= Type.HOURLY.ordinal() && snapshotType <= Type.MONTHLY.ordinal() ) { + public boolean isRecursive() { + if (snapshotType >= Type.HOURLY.ordinal() && snapshotType <= Type.MONTHLY.ordinal()) { return true; } return false; @@ -224,6 +223,7 @@ public class SnapshotVO { public String getTypeDescription() { return typeDescription; } + public void setTypeDescription(String typeDescription) { this.typeDescription = typeDescription; } @@ -252,25 +252,25 @@ public class SnapshotVO { this.status = status; } - public String getBackupSnapshotId(){ + public String getBackupSnapshotId() { return backupSnapshotId; } - public long getPrevSnapshotId(){ + public long getPrevSnapshotId() { return prevSnapshotId; } - public void setBackupSnapshotId(String backUpSnapshotId){ + public void setBackupSnapshotId(String backUpSnapshotId) { this.backupSnapshotId = backUpSnapshotId; } - public void setPrevSnapshotId(long prevSnapshotId){ + public void setPrevSnapshotId(long prevSnapshotId) { this.prevSnapshotId = prevSnapshotId; } public static Type getSnapshotType(String snapshotType) { - for ( Type type : Type.values()) { - if ( type.equals(snapshotType)) { + for (Type type : Type.values()) { + if (type.equals(snapshotType)) { return type; } } diff --git a/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java b/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java index e722ab55c70..317521de734 100644 --- a/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java +++ b/engine/storage/snapshot/test/src/SnapshotDataFactoryTest.java @@ -18,33 +18,24 @@ */ package src; -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import com.cloud.utils.component.ComponentContext; - import junit.framework.TestCase; //@RunWith(SpringJUnit4ClassRunner.class) //@ContextConfiguration(locations = "classpath:/SnapshotManagerTestContext.xml") public class SnapshotDataFactoryTest extends TestCase { - //@Inject SnapshotDataFactory snapshotFactory; - + // @Inject SnapshotDataFactory snapshotFactory; + @Before public void setup() throws Exception { - //ComponentContext.initComponentsLifeCycle(); - + // ComponentContext.initComponentsLifeCycle(); + } - + @Test public void testGestSnapshot() { - //snapshotFactory.getSnapshot(snapshotId); + // snapshotFactory.getSnapshot(snapshotId); } - + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/BaseType.java b/engine/storage/src/org/apache/cloudstack/storage/BaseType.java index a5b45e17f03..539792628c1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/BaseType.java +++ b/engine/storage/src/org/apache/cloudstack/storage/BaseType.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.storage; public abstract class BaseType { + @Override public boolean equals(Object that) { if (this == that) { return true; diff --git a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java deleted file mode 100644 index 01611be3c42..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/HostEndpointRpcServer.java +++ /dev/null @@ -1,29 +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; - -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; - -public interface HostEndpointRpcServer { - void sendCommandAsync(RemoteHostEndPoint ep, final Command command, final AsyncCompletionCallback callback); - Answer sendCommand(RemoteHostEndPoint ep, final Command command); -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java b/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java deleted file mode 100644 index 5675b73b662..00000000000 --- a/engine/storage/src/org/apache/cloudstack/storage/HypervisorHostEndPointRpcServer.java +++ /dev/null @@ -1,119 +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; - -import javax.annotation.PostConstruct; -import javax.inject.Inject; - -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.framework.rpc.RpcCallbackListener; -import org.apache.cloudstack.framework.rpc.RpcException; -import org.apache.cloudstack.framework.rpc.RpcProvider; -import org.apache.cloudstack.framework.rpc.RpcServiceDispatcher; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.Command; -import com.cloud.utils.exception.CloudRuntimeException; - -@Component -public class HypervisorHostEndPointRpcServer implements HostEndpointRpcServer { - private static final Logger s_logger = Logger.getLogger(HypervisorHostEndPointRpcServer.class); - - @Inject - private RpcProvider rpcProvider; - - public HypervisorHostEndPointRpcServer() { - } - - public HypervisorHostEndPointRpcServer(RpcProvider rpcProvider) { - rpcProvider = rpcProvider; - rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); - } - - @PostConstruct - public void Initialize() { - rpcProvider.registerRpcServiceEndpoint(RpcServiceDispatcher.getDispatcher(this)); - } - - @Override - public void sendCommandAsync(RemoteHostEndPoint host, final Command command, final AsyncCompletionCallback callback) { - rpcProvider.newCall(host.getHostAddr()).addCallbackListener(new RpcCallbackListener() { - @Override - public void onSuccess(Answer result) { - callback.complete(result); - } - - @Override - public void onFailure(RpcException e) { - Answer answer = new Answer(command, false, e.toString()); - callback.complete(answer); - } - }).apply(); - } - - private class SendCommandContext extends AsyncRpcConext { - private T answer; - - public SendCommandContext(AsyncCompletionCallback callback) { - super(callback); - } - - public void setAnswer(T answer) { - this.answer = answer; - } - - public T getAnswer() { - return this.answer; - } - - } - - @Override - public Answer sendCommand(RemoteHostEndPoint host, Command command) { - SendCommandContext context = new SendCommandContext(null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().sendCommandCallback(null, null)) - .setContext(context); - - this.sendCommandAsync(host, command, caller); - - synchronized (context) { - try { - context.wait(); - } catch (InterruptedException e) { - s_logger.debug(e.toString()); - throw new CloudRuntimeException("wait on context is interrupted", e); - } - } - - return context.getAnswer(); - } - - protected Object sendCommandCallback(AsyncCallbackDispatcher callback, SendCommandContext context) { - context.setAnswer((Answer)callback.getResult()); - synchronized(context) { - context.notify(); - } - return null; - } -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java index c0957916e7d..18fcd7178d2 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/LocalHostEndpoint.java @@ -26,38 +26,34 @@ import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.resource.LocalNfsSecondaryStorageResource; -import com.cloud.agent.Listener; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.resource.ServerResource; -import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.download.DownloadListener; import com.cloud.utils.net.NetUtils; public class LocalHostEndpoint implements EndPoint { - private ScheduledExecutorService executor; - protected ServerResource resource; - public LocalHostEndpoint() { + private ScheduledExecutorService executor; + protected ServerResource resource; + + public LocalHostEndpoint() { resource = new LocalNfsSecondaryStorageResource(); - executor = Executors.newScheduledThreadPool(10); - } - @Override - public long getId() { - // TODO Auto-generated method stub - return 0; - } + executor = Executors.newScheduledThreadPool(10); + } + @Override + public long getId() { + // TODO Auto-generated method stub + return 0; + } - @Override + @Override public String getHostAddr() { return "127.0.0.0"; } - @Override public String getPublicAddr() { - String hostIp= NetUtils.getDefaultHostIp(); + String hostIp = NetUtils.getDefaultHostIp(); if (hostIp != null) return hostIp; else @@ -65,70 +61,41 @@ public class LocalHostEndpoint implements EndPoint { } @Override - public Answer sendMessage(Command cmd) { - if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand)) { - return resource.executeRequest(cmd); - } - // TODO Auto-generated method stub - return new Answer(cmd, false, "unsupported command:" + cmd.toString()); - } + public Answer sendMessage(Command cmd) { + if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand)) { + return resource.executeRequest(cmd); + } + // TODO Auto-generated method stub + return new Answer(cmd, false, "unsupported command:" + cmd.toString()); + } - private class CmdRunner implements Runnable { - final Command cmd; - final AsyncCompletionCallback callback; - public CmdRunner(Command cmd, AsyncCompletionCallback callback) { - this.cmd = cmd; - this.callback = callback; - } - @Override - public void run() { - Answer answer = sendMessage(cmd); - callback.complete(answer); - } - } + private class CmdRunner implements Runnable { + final Command cmd; + final AsyncCompletionCallback callback; - private class CmdRunner2 implements Runnable { - final Command cmd; - final Listener listener; - public CmdRunner2(Command cmd, Listener listener) { - this.cmd = cmd; - this.listener = listener; - } - @Override - public void run() { - try { - DownloadAnswer answer = (DownloadAnswer) sendMessage(cmd); - Answer[] answers = new Answer[1]; - answers[0] = answer; - listener.processAnswers(getId(), 0, answers); - if (listener instanceof DownloadListener) { - DownloadListener dwldListener = (DownloadListener)listener; - dwldListener.getCallback().complete(answer); - } - } catch (Exception ex) { - DownloadAnswer fail = new DownloadAnswer("Error in handling DownloadCommand : " + ex.getMessage(), VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR); - Answer[] answers = new Answer[1]; - answers[0] = fail; - listener.processAnswers(getId(), 0, answers); - if (listener instanceof DownloadListener) { - DownloadListener dwldListener = (DownloadListener)listener; - dwldListener.getCallback().complete(fail); - } - } - } - } - @Override + public CmdRunner(Command cmd, AsyncCompletionCallback callback) { + this.cmd = cmd; + this.callback = callback; + } + + @Override + public void run() { + Answer answer = sendMessage(cmd); + callback.complete(answer); + } + } + + @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { - executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); - } + executor.schedule(new CmdRunner(cmd, callback), 10, TimeUnit.SECONDS); + } public ServerResource getResource() { return resource; } + public void setResource(ServerResource resource) { this.resource = resource; } - - } diff --git a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java index 5b0debba344..cd64ab2457c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java +++ b/engine/storage/src/org/apache/cloudstack/storage/RemoteHostEndPoint.java @@ -47,19 +47,17 @@ import com.cloud.utils.exception.CloudRuntimeException; public class RemoteHostEndPoint implements EndPoint { private static final Logger s_logger = Logger.getLogger(RemoteHostEndPoint.class); - private long hostId; - private String hostAddress; - private String publicAddress; + private long hostId; + private String hostAddress; + private String publicAddress; @Inject AgentManager agentMgr; @Inject - HostEndpointRpcServer rpcServer; - @Inject protected HypervisorGuruManager _hvGuruMgr; private ScheduledExecutorService executor; public RemoteHostEndPoint() { - executor = Executors.newScheduledThreadPool(10); + executor = Executors.newScheduledThreadPool(10); } private void configure(long hostId, String hostAddress, String publicAddress) { @@ -79,7 +77,7 @@ public class RemoteHostEndPoint implements EndPoint { return this.hostAddress; } - + @Override public String getPublicAddr() { return this.publicAddress; } @@ -91,27 +89,27 @@ public class RemoteHostEndPoint implements EndPoint { @Override public Answer sendMessage(Command cmd) { - String errMsg = null; - try { - long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd); - return agentMgr.send(newHostId, cmd); - } catch (AgentUnavailableException e) { - errMsg = e.toString(); - s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); - } catch (OperationTimedoutException e) { - errMsg = e.toString(); - s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); - } - throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg); + String errMsg = null; + try { + long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd); + return agentMgr.send(newHostId, cmd); + } catch (AgentUnavailableException e) { + errMsg = e.toString(); + s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); + } catch (OperationTimedoutException e) { + errMsg = e.toString(); + s_logger.debug("Failed to send command, due to Agent:" + getId() + ", " + e.toString()); + } + throw new CloudRuntimeException("Failed to send command, due to Agent:" + getId() + ", " + errMsg); } private class CmdRunner implements Listener, Runnable { - final AsyncCompletionCallback callback; + final AsyncCompletionCallback callback; Answer answer; public CmdRunner(AsyncCompletionCallback callback) { - this.callback = callback; - } + this.callback = callback; + } @Override public boolean processAnswers(long agentId, long seq, Answer[] answers) { @@ -166,12 +164,12 @@ public class RemoteHostEndPoint implements EndPoint { public void run() { callback.complete(answer); } - } + } @Override public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback) { try { - long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(this.hostId, cmd); + long newHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(this.hostId, cmd); agentMgr.send(newHostId, new Commands(cmd), new CmdRunner(callback)); } catch (AgentUnavailableException e) { throw new CloudRuntimeException("Unable to send message", e); diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java index 3a66b859b39..010e4685b20 100755 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/AbstractStoragePoolAllocator.java @@ -53,140 +53,153 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; public abstract class AbstractStoragePoolAllocator extends AdapterBase implements StoragePoolAllocator { - private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class); - @Inject StorageManager storageMgr; - protected @Inject PrimaryDataStoreDao _storagePoolDao; - @Inject VolumeDao _volumeDao; - @Inject ConfigurationDao _configDao; - @Inject ClusterDao _clusterDao; - protected @Inject DataStoreManager dataStoreMgr; - protected BigDecimal _storageOverprovisioningFactor = new BigDecimal(1); + private static final Logger s_logger = Logger.getLogger(AbstractStoragePoolAllocator.class); + @Inject + StorageManager storageMgr; + protected @Inject + PrimaryDataStoreDao _storagePoolDao; + @Inject + VolumeDao _volumeDao; + @Inject + ConfigurationDao _configDao; + @Inject + ClusterDao _clusterDao; + protected @Inject + DataStoreManager dataStoreMgr; + protected BigDecimal _storageOverprovisioningFactor = new BigDecimal(1); long _extraBytesPerVolume = 0; Random _rand; boolean _dontMatter; protected String _allocationAlgorithm = "random"; @Inject DiskOfferingDao _diskOfferingDao; - + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); - + Map configs = _configDao.getConfiguration(null, params); - + String globalStorageOverprovisioningFactor = configs.get("storage.overprovisioning.factor"); - _storageOverprovisioningFactor = new BigDecimal(NumbersUtil.parseFloat(globalStorageOverprovisioningFactor, 2.0f)); - + _storageOverprovisioningFactor = new BigDecimal(NumbersUtil.parseFloat(globalStorageOverprovisioningFactor, + 2.0f)); + _extraBytesPerVolume = 0; - + _rand = new Random(System.currentTimeMillis()); _dontMatter = Boolean.parseBoolean(configs.get("storage.overwrite.provisioning")); String allocationAlgorithm = configs.get("vm.allocation.algorithm"); if (allocationAlgorithm != null) { - _allocationAlgorithm = allocationAlgorithm; + _allocationAlgorithm = allocationAlgorithm; } return true; } - - protected abstract List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); - + + protected abstract List select(DiskProfile dskCh, + VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, + int returnUpTo); + @Override - public - List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { - List pools = select(dskCh, vmProfile, plan, avoid, returnUpTo); - return reOrder(pools, vmProfile, plan); + public List allocateToPool(DiskProfile dskCh, + VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, + int returnUpTo) { + List pools = select(dskCh, vmProfile, plan, avoid, returnUpTo); + return reOrder(pools, vmProfile, plan); } - - protected List reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List pools, Account account) { - if(account == null){ + + protected List reorderPoolsByNumberOfVolumes(DeploymentPlan plan, List pools, + Account account) { + if (account == null) { return pools; } long dcId = plan.getDataCenterId(); Long podId = plan.getPodId(); Long clusterId = plan.getClusterId(); - - List poolIdsByVolCount = _volumeDao.listPoolIdsByVolumeCount(dcId, podId, clusterId, account.getAccountId()); + + List poolIdsByVolCount = _volumeDao.listPoolIdsByVolumeCount(dcId, podId, clusterId, + account.getAccountId()); if (s_logger.isDebugEnabled()) { - s_logger.debug("List of pools in ascending order of number of volumes for account id: "+ account.getAccountId() + " is: "+ poolIdsByVolCount); + s_logger.debug("List of pools in ascending order of number of volumes for account id: " + + account.getAccountId() + " is: " + poolIdsByVolCount); } - - //now filter the given list of Pools by this ordered list - Map poolMap = new HashMap(); + + // now filter the given list of Pools by this ordered list + Map poolMap = new HashMap(); for (StoragePool pool : pools) { poolMap.put(pool.getId(), pool); } List matchingPoolIds = new ArrayList(poolMap.keySet()); - + poolIdsByVolCount.retainAll(matchingPoolIds); - + List reorderedPools = new ArrayList(); - for(Long id: poolIdsByVolCount){ + for (Long id : poolIdsByVolCount) { reorderedPools.add(poolMap.get(id)); } - + return reorderedPools; } - - protected List reOrder(List pools, - VirtualMachineProfile vmProfile, - DeploymentPlan plan) { - Account account = null; - if(vmProfile.getVirtualMachine() != null){ - account = vmProfile.getOwner(); - } - - if(_allocationAlgorithm.equals("random") || _allocationAlgorithm.equals("userconcentratedpod_random") || (account == null)) { - // Shuffle this so that we don't check the pools in the same order. - Collections.shuffle(pools); - }else if(_allocationAlgorithm.equals("userdispersing")){ - pools = reorderPoolsByNumberOfVolumes(plan, pools, account); - } - return pools; - } - - protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, - DeploymentPlan plan) { - - if (s_logger.isDebugEnabled()) { - s_logger.debug("Checking if storage pool is suitable, name: " + pool.getName()+ " ,poolId: "+ pool.getId()); + + protected List reOrder(List pools, + VirtualMachineProfile vmProfile, DeploymentPlan plan) { + Account account = null; + if (vmProfile.getVirtualMachine() != null) { + account = vmProfile.getOwner(); } - if (avoid.shouldAvoid(pool)) { - if (s_logger.isDebugEnabled()) { + + if (_allocationAlgorithm.equals("random") || _allocationAlgorithm.equals("userconcentratedpod_random") + || (account == null)) { + // Shuffle this so that we don't check the pools in the same order. + Collections.shuffle(pools); + } else if (_allocationAlgorithm.equals("userdispersing")) { + pools = reorderPoolsByNumberOfVolumes(plan, pools, account); + } + return pools; + } + + protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, DeploymentPlan plan) { + + if (s_logger.isDebugEnabled()) { + s_logger.debug("Checking if storage pool is suitable, name: " + pool.getName() + " ,poolId: " + + pool.getId()); + } + if (avoid.shouldAvoid(pool)) { + if (s_logger.isDebugEnabled()) { s_logger.debug("StoragePool is in avoid set, skipping this pool"); - } - return false; - } - - if(dskCh.getType().equals(Type.ROOT) && pool.getPoolType().equals(StoragePoolType.Iscsi)){ - if (s_logger.isDebugEnabled()) { - s_logger.debug("Disk needed for ROOT volume, but StoragePoolType is Iscsi, skipping this and trying other available pools"); - } + } return false; } - + + if (dskCh.getType().equals(Type.ROOT) && pool.getPoolType().equals(StoragePoolType.Iscsi)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Disk needed for ROOT volume, but StoragePoolType is Iscsi, skipping this and trying other available pools"); + } + return false; + } + DiskOfferingVO diskOffering = _diskOfferingDao.findById(dskCh.getDiskOfferingId()); if (diskOffering.getSystemUse() && pool.getPoolType() == StoragePoolType.RBD) { - s_logger.debug("Skipping RBD pool " + pool.getName() + " as a suitable pool. RBD is not supported for System VM's"); + s_logger.debug("Skipping RBD pool " + pool.getName() + + " as a suitable pool. RBD is not supported for System VM's"); return false; } - - Long clusterId = pool.getClusterId(); - ClusterVO cluster = _clusterDao.findById(clusterId); - if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) { - if (s_logger.isDebugEnabled()) { + Long clusterId = pool.getClusterId(); + ClusterVO cluster = _clusterDao.findById(clusterId); + if (!(cluster.getHypervisorType() == dskCh.getHypervisorType())) { + if (s_logger.isDebugEnabled()) { s_logger.debug("StoragePool's Cluster does not have required hypervisorType, skipping this pool"); } - return false; - } + return false; + } - // check capacity - Volume volume = _volumeDao.findById(dskCh.getVolumeId()); + // check capacity + Volume volume = _volumeDao.findById(dskCh.getVolumeId()); List requestVolumes = new ArrayList(); requestVolumes.add(volume); return storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool); - } + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java index 5b1f8cd699a..0933adcd3bc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ClusterScopeStoragePoolAllocator.java @@ -40,7 +40,7 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; @Component -@Local(value=StoragePoolAllocator.class) +@Local(value = StoragePoolAllocator.class) public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocator { private static final Logger s_logger = Logger.getLogger(ClusterScopeStoragePoolAllocator.class); protected String _allocationAlgorithm = "random"; @@ -49,19 +49,21 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat DiskOfferingDao _diskOfferingDao; @Override - protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { s_logger.debug("ClusterScopeStoragePoolAllocator looking for storage pool"); - List suitablePools = new ArrayList(); + List suitablePools = new ArrayList(); - long dcId = plan.getDataCenterId(); - Long podId = plan.getPodId(); - Long clusterId = plan.getClusterId(); + long dcId = plan.getDataCenterId(); + Long podId = plan.getPodId(); + Long clusterId = plan.getClusterId(); - if(dskCh.getTags() != null && dskCh.getTags().length != 0){ - s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + " having tags:" + Arrays.toString(dskCh.getTags())); - }else{ - s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId); + if (dskCh.getTags() != null && dskCh.getTags().length != 0) { + s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId + + " having tags:" + Arrays.toString(dskCh.getTags())); + } else { + s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId); } List pools = _storagePoolDao.findPoolsByTags(dcId, podId, clusterId, dskCh.getTags()); @@ -75,30 +77,31 @@ public class ClusterScopeStoragePoolAllocator extends AbstractStoragePoolAllocat if (pools.size() == 0) { if (s_logger.isDebugEnabled()) { - String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString(); + String storageType = dskCh.useLocalStorage() ? ServiceOffering.StorageType.local.toString() + : ServiceOffering.StorageType.shared.toString(); s_logger.debug("No storage pools available for " + storageType + " volume allocation, returning"); } return suitablePools; } - for (StoragePoolVO pool: pools) { - if(suitablePools.size() == returnUpTo){ - break; - } - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId()); - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); + for (StoragePoolVO pool : pools) { + if (suitablePools.size() == returnUpTo) { + break; + } + StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + if (filter(avoid, pol, dskCh, plan)) { + suitablePools.add(pol); } else { avoid.addPool(pool.getId()); - } + } } if (s_logger.isDebugEnabled()) { - s_logger.debug("FirstFitStoragePoolAllocator returning "+suitablePools.size() +" suitable storage pools"); + s_logger.debug("FirstFitStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools"); } return suitablePools; - } + } @Override public boolean configure(String name, Map params) throws ConfigurationException { diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java index 02032ee4fbd..979ea73cd23 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/GarbageCollectingStoragePoolAllocator.java @@ -36,18 +36,21 @@ import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -@Local(value=StoragePoolAllocator.class) +@Local(value = StoragePoolAllocator.class) public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAllocator { private static final Logger s_logger = Logger.getLogger(GarbageCollectingStoragePoolAllocator.class); StoragePoolAllocator _firstFitStoragePoolAllocator; StoragePoolAllocator _localStoragePoolAllocator; - @Inject StorageManager storageMgr; - @Inject ConfigurationDao _configDao; + @Inject + StorageManager storageMgr; + @Inject + ConfigurationDao _configDao; boolean _storagePoolCleanupEnabled; @Override - public List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + public List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { s_logger.debug("GarbageCollectingStoragePoolAllocator looking for storage pool"); if (!_storagePoolCleanupEnabled) { s_logger.debug("Storage pool cleanup is not enabled, so GarbageCollectingStoragePoolAllocator is being skipped."); @@ -65,7 +68,8 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl } // Try to find a storage pool after cleanup - ExcludeList myAvoids = new ExcludeList(avoid.getDataCentersToAvoid(), avoid.getPodsToAvoid(), avoid.getClustersToAvoid(), avoid.getHostsToAvoid(), avoid.getPoolsToAvoid()); + ExcludeList myAvoids = new ExcludeList(avoid.getDataCentersToAvoid(), avoid.getPodsToAvoid(), + avoid.getClustersToAvoid(), avoid.getHostsToAvoid(), avoid.getPoolsToAvoid()); return allocator.allocateToPool(dskCh, vmProfile, plan, myAvoids, returnUpTo); } @@ -80,7 +84,8 @@ public class GarbageCollectingStoragePoolAllocator extends AbstractStoragePoolAl _localStoragePoolAllocator.configure("GCLocalStoragePoolAllocator", params); String storagePoolCleanupEnabled = _configDao.getValue("storage.pool.cleanup.enabled"); - _storagePoolCleanupEnabled = (storagePoolCleanupEnabled == null) ? true : Boolean.parseBoolean(storagePoolCleanupEnabled); + _storagePoolCleanupEnabled = (storagePoolCleanupEnabled == null) ? true : Boolean + .parseBoolean(storagePoolCleanupEnabled); return true; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java index 632ba439cb0..ef9e84eee15 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/LocalStoragePoolAllocator.java @@ -65,7 +65,8 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { ConfigurationDao _configDao; @Override - protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { List suitablePools = new ArrayList(); @@ -78,13 +79,13 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { // data disk and host identified from deploying vm (attach volume case) if (dskCh.getType() == Volume.Type.DATADISK && plan.getHostId() != null) { List hostPools = _poolHostDao.listByHostId(plan.getHostId()); - for (StoragePoolHostVO hostPool: hostPools) { + for (StoragePoolHostVO hostPool : hostPools) { StoragePoolVO pool = _storagePoolDao.findById(hostPool.getPoolId()); if (pool != null && pool.isLocal()) { - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId()); - if (filter(avoid, pol, dskCh, plan)) { - s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list"); - suitablePools.add(pol); + StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + if (filter(avoid, pol, dskCh, plan)) { + s_logger.debug("Found suitable local storage pool " + pool.getId() + ", adding to list"); + suitablePools.add(pol); } else { avoid.addPool(pool.getId()); } @@ -95,18 +96,19 @@ public class LocalStoragePoolAllocator extends AbstractStoragePoolAllocator { } } } else { - List availablePools = _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), plan.getPodId(), plan.getClusterId(), dskCh.getTags()); - for (StoragePoolVO pool : availablePools) { - if (suitablePools.size() == returnUpTo) { - break; - } - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId()); - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); + List availablePools = _storagePoolDao.findLocalStoragePoolsByTags(plan.getDataCenterId(), + plan.getPodId(), plan.getClusterId(), dskCh.getTags()); + for (StoragePoolVO pool : availablePools) { + if (suitablePools.size() == returnUpTo) { + break; + } + StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + if (filter(avoid, pol, dskCh, plan)) { + suitablePools.add(pol); } else { avoid.addPool(pool.getId()); } - } + } // add remaining pools in cluster, that did not match tags, to avoid // set diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java index 4663b12e97e..d0571382191 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/UseLocalForRootAllocator.java @@ -34,22 +34,24 @@ import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -@Local(value=StoragePoolAllocator.class) +@Local(value = StoragePoolAllocator.class) public class UseLocalForRootAllocator extends LocalStoragePoolAllocator implements StoragePoolAllocator { @Inject DataCenterDao _dcDao; @Override - public List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + public List allocateToPool(DiskProfile dskCh, + VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, + int returnUpTo) { DataCenterVO dc = _dcDao.findById(plan.getDataCenterId()); if (!dc.isLocalStorageEnabled()) { return null; } - + return super.allocateToPool(dskCh, vmProfile, plan, avoid, returnUpTo); } - + @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); diff --git a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java index e9769802a37..8155edfb8cd 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java +++ b/engine/storage/src/org/apache/cloudstack/storage/allocator/ZoneWideStoragePoolAllocator.java @@ -38,34 +38,35 @@ import com.cloud.vm.VirtualMachineProfile; @Component public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { - private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class); - @Inject PrimaryDataStoreDao _storagePoolDao; - @Inject DataStoreManager dataStoreMgr; + private static final Logger s_logger = Logger.getLogger(ZoneWideStoragePoolAllocator.class); + @Inject + PrimaryDataStoreDao _storagePoolDao; + @Inject + DataStoreManager dataStoreMgr; - @Override - protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, - DeploymentPlan plan) { - Volume volume = _volumeDao.findById(dskCh.getVolumeId()); + @Override + protected boolean filter(ExcludeList avoid, StoragePool pool, DiskProfile dskCh, DeploymentPlan plan) { + Volume volume = _volumeDao.findById(dskCh.getVolumeId()); List requestVolumes = new ArrayList(); requestVolumes.add(volume); return storageMgr.storagePoolHasEnoughSpace(requestVolumes, pool); - } + } - @Override - protected List select(DiskProfile dskCh, - VirtualMachineProfile vmProfile, - DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { - s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool"); - List suitablePools = new ArrayList(); - HypervisorType hypervisor = dskCh.getHypervisorType(); - if (hypervisor != null) { - if (hypervisor != HypervisorType.KVM) { - s_logger.debug("Only kvm supports zone wide storage"); - return suitablePools; - } - } + @Override + protected List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + s_logger.debug("ZoneWideStoragePoolAllocator to find storage pool"); + List suitablePools = new ArrayList(); + HypervisorType hypervisor = dskCh.getHypervisorType(); + if (hypervisor != null) { + if (hypervisor != HypervisorType.KVM) { + s_logger.debug("Only kvm supports zone wide storage"); + return suitablePools; + } + } - List storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), dskCh.getTags()); + List storagePools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), + dskCh.getTags()); // add remaining pools in zone, that did not match tags, to avoid set List allPools = _storagePoolDao.findZoneWideStoragePoolsByTags(plan.getDataCenterId(), null); @@ -74,17 +75,17 @@ public class ZoneWideStoragePoolAllocator extends AbstractStoragePoolAllocator { avoid.addPool(pool.getId()); } - for (StoragePoolVO storage : storagePools) { - if (suitablePools.size() == returnUpTo) { - break; - } - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(storage.getId()); - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); + for (StoragePoolVO storage : storagePools) { + if (suitablePools.size() == returnUpTo) { + break; + } + StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(storage.getId()); + if (filter(avoid, pol, dskCh, plan)) { + suitablePools.add(pol); } else { avoid.addPool(pol.getId()); } - } - return suitablePools; - } + } + return suitablePools; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java b/engine/storage/src/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java index 5f5ce2f4a92..36da9665bcc 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java +++ b/engine/storage/src/org/apache/cloudstack/storage/backup/SnapshotOnBackupStoreInfo.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.storage.backup; import org.apache.cloudstack.storage.backup.datastore.BackupStoreInfo; public interface SnapshotOnBackupStoreInfo { - public String getName(); - public BackupStoreInfo getBackupStore(); + public String getName(); + + public BackupStoreInfo getBackupStore(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java b/engine/storage/src/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java index ca1454af570..fc41d4739c1 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java +++ b/engine/storage/src/org/apache/cloudstack/storage/backup/datastore/BackupStoreInfo.java @@ -19,6 +19,7 @@ package org.apache.cloudstack.storage.backup.datastore; import org.apache.cloudstack.storage.backup.SnapshotOnBackupStoreInfo; public interface BackupStoreInfo { - public SnapshotOnBackupStoreInfo getSnapshot(long snapshotId); - public boolean deleteSnapshot(SnapshotOnBackupStoreInfo snapshot); + public SnapshotOnBackupStoreInfo getSnapshot(long snapshotId); + + public boolean deleteSnapshot(SnapshotOnBackupStoreInfo snapshot); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java index 177dc3e89e7..ef215284ddd 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManager.java @@ -25,13 +25,18 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; public interface DataObjectManager { - public void createAsync(DataObject data, DataStore store, AsyncCompletionCallback callback, boolean noCopy); + public void createAsync(DataObject data, DataStore store, AsyncCompletionCallback callback, + boolean noCopy); + /* - * Only create internal state, without actually send down create command. + * Only create internal state, without actually send down create command. * It's up to device driver decides whether to create object before copying */ public DataObject createInternalStateOnly(DataObject data, DataStore store); + public void update(DataObject data, String path, Long size); + public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); + public void deleteAsync(DataObject data, AsyncCompletionCallback callback); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java index bcd327faae9..6e97e6f9f74 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataObjectManagerImpl.java @@ -40,17 +40,15 @@ import com.cloud.utils.fsm.NoTransitionException; @Component public class DataObjectManagerImpl implements DataObjectManager { - private static final Logger s_logger = Logger - .getLogger(DataObjectManagerImpl.class); + private static final Logger s_logger = Logger.getLogger(DataObjectManagerImpl.class); @Inject ObjectInDataStoreManager objectInDataStoreMgr; @Inject DataMotionService motionSrv; protected long waitingTime = 1800; // half an hour protected long waitingRetries = 10; - - protected DataObject waitingForCreated(DataObject dataObj, - DataStore dataStore) { + + protected DataObject waitingForCreated(DataObject dataObj, DataStore dataStore) { long retries = this.waitingRetries; DataObjectInStore obj = null; do { @@ -61,8 +59,7 @@ public class DataObjectManagerImpl implements DataObjectManager { throw new CloudRuntimeException("sleep interrupted", e); } - obj = objectInDataStoreMgr.findObject(dataObj, - dataStore); + obj = objectInDataStoreMgr.findObject(dataObj, dataStore); if (obj == null) { s_logger.debug("can't find object in db, maybe it's cleaned up already, exit waiting"); break; @@ -75,40 +72,35 @@ public class DataObjectManagerImpl implements DataObjectManager { if (obj == null || retries <= 0) { s_logger.debug("waiting too long for template downloading, marked it as failed"); - throw new CloudRuntimeException( - "waiting too long for template downloading, marked it as failed"); + throw new CloudRuntimeException("waiting too long for template downloading, marked it as failed"); } return objectInDataStoreMgr.get(dataObj, dataStore); } + class CreateContext extends AsyncRpcConext { final DataObject objInStrore; - public CreateContext(AsyncCompletionCallback callback, - DataObject objInStore) { + public CreateContext(AsyncCompletionCallback callback, DataObject objInStore) { super(callback); - this.objInStrore = objInStore; + this.objInStrore = objInStore; } } - + @Override - public void createAsync(DataObject data, DataStore store, - AsyncCompletionCallback callback, boolean noCopy) { - DataObjectInStore obj = objectInDataStoreMgr.findObject( - data, store); + public void createAsync(DataObject data, DataStore store, AsyncCompletionCallback callback, + boolean noCopy) { + DataObjectInStore obj = objectInDataStoreMgr.findObject(data, store); DataObject objInStore = null; boolean freshNewTemplate = false; if (obj == null) { try { - objInStore = objectInDataStoreMgr.create( - data, store); + objInStore = objectInDataStoreMgr.create(data, store); freshNewTemplate = true; } catch (Throwable e) { - obj = objectInDataStoreMgr.findObject(data, - store); + obj = objectInDataStoreMgr.findObject(data, store); if (obj == null) { - CreateCmdResult result = new CreateCmdResult( - null, null); + CreateCmdResult result = new CreateCmdResult(null, null); result.setSuccess(false); result.setResult(e.toString()); callback.complete(result); @@ -117,11 +109,9 @@ public class DataObjectManagerImpl implements DataObjectManager { } } - if (!freshNewTemplate - && obj.getState() != ObjectInDataStoreStateMachine.State.Ready) { + if (!freshNewTemplate && obj.getState() != ObjectInDataStoreStateMachine.State.Ready) { try { - objInStore = waitingForCreated( - data, store); + objInStore = waitingForCreated(data, store); } catch (Exception e) { CreateCmdResult result = new CreateCmdResult(null, null); result.setSuccess(false); @@ -130,8 +120,7 @@ public class DataObjectManagerImpl implements DataObjectManager { return; } - CreateCmdResult result = new CreateCmdResult( - null, null); + CreateCmdResult result = new CreateCmdResult(null, null); callback.complete(result); return; } @@ -143,12 +132,10 @@ public class DataObjectManagerImpl implements DataObjectManager { } else { event = ObjectInDataStoreStateMachine.Event.CreateRequested; } - objectInDataStoreMgr.update(objInStore, - event); + objectInDataStoreMgr.update(objInStore, event); } catch (NoTransitionException e) { try { - objectInDataStoreMgr.update(objInStore, - ObjectInDataStoreStateMachine.Event.OperationFailed); + objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationFailed); } catch (NoTransitionException e1) { s_logger.debug("state transation failed", e1); } @@ -159,24 +146,19 @@ public class DataObjectManagerImpl implements DataObjectManager { return; } - CreateContext context = new CreateContext( - callback, objInStore); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().createAsynCallback(null, null)) - .setContext(context); + CreateContext context = new CreateContext(callback, objInStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createAsynCallback(null, null)).setContext(context); store.getDriver().createAsync(objInStore, caller); return; } - + protected Void createAsynCallback(AsyncCallbackDispatcher callback, CreateContext context) { CreateCmdResult result = callback.getResult(); DataObject objInStrore = context.objInStrore; - CreateCmdResult upResult = new CreateCmdResult( - null, null); + CreateCmdResult upResult = new CreateCmdResult(null, null); if (result.isFailed()) { upResult.setResult(result.getResult()); context.getParentCallback().complete(upResult); @@ -184,12 +166,10 @@ public class DataObjectManagerImpl implements DataObjectManager { } try { - objectInDataStoreMgr.update(objInStrore, - ObjectInDataStoreStateMachine.Event.OperationSuccessed); + objectInDataStoreMgr.update(objInStrore, ObjectInDataStoreStateMachine.Event.OperationSuccessed); } catch (NoTransitionException e) { try { - objectInDataStoreMgr.update(objInStrore, - ObjectInDataStoreStateMachine.Event.OperationFailed); + objectInDataStoreMgr.update(objInStrore, ObjectInDataStoreStateMachine.Event.OperationFailed); } catch (NoTransitionException e1) { s_logger.debug("failed to change state", e1); } @@ -198,18 +178,16 @@ public class DataObjectManagerImpl implements DataObjectManager { context.getParentCallback().complete(upResult); return null; } - + context.getParentCallback().complete(result); return null; } - + class CopyContext extends AsyncRpcConext { DataObject destObj; DataObject srcObj; - public CopyContext(AsyncCompletionCallback callback, - DataObject srcObj, - DataObject destObj) { + public CopyContext(AsyncCompletionCallback callback, DataObject srcObj, DataObject destObj) { super(callback); this.srcObj = srcObj; this.destObj = destObj; @@ -217,16 +195,13 @@ public class DataObjectManagerImpl implements DataObjectManager { } @Override - public void copyAsync(DataObject srcData, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback) { try { - objectInDataStoreMgr.update(destData, - ObjectInDataStoreStateMachine.Event.CopyingRequested); + objectInDataStoreMgr.update(destData, ObjectInDataStoreStateMachine.Event.CopyingRequested); } catch (NoTransitionException e) { s_logger.debug("failed to change state", e); try { - objectInDataStoreMgr.update(destData, - ObjectInDataStoreStateMachine.Event.OperationFailed); + objectInDataStoreMgr.update(destData, ObjectInDataStoreStateMachine.Event.OperationFailed); } catch (NoTransitionException e1) { } @@ -235,18 +210,14 @@ public class DataObjectManagerImpl implements DataObjectManager { callback.complete(res); } - CopyContext anotherCall = new CopyContext( - callback, srcData, destData); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback(caller.getTarget().copyCallback(null, null)) - .setContext(anotherCall); + CopyContext anotherCall = new CopyContext(callback, srcData, destData); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyCallback(null, null)).setContext(anotherCall); motionSrv.copyAsync(srcData, destData, caller); } - - protected Void copyCallback( - AsyncCallbackDispatcher callback, + + protected Void copyCallback(AsyncCallbackDispatcher callback, CopyContext context) { CopyCommandResult result = callback.getResult(); DataObject destObj = context.destObj; @@ -257,66 +228,56 @@ public class DataObjectManagerImpl implements DataObjectManager { } catch (NoTransitionException e) { s_logger.debug("Failed to update copying state", e); } - CreateCmdResult res = new CreateCmdResult( - null, null); + CreateCmdResult res = new CreateCmdResult(null, null); res.setResult(result.getResult()); context.getParentCallback().complete(res); } try { - objectInDataStoreMgr.update(destObj, - ObjectInDataStoreStateMachine.Event.OperationSuccessed); + objectInDataStoreMgr.update(destObj, ObjectInDataStoreStateMachine.Event.OperationSuccessed); } catch (NoTransitionException e) { s_logger.debug("Failed to update copying state: ", e); try { - objectInDataStoreMgr.update(destObj, - ObjectInDataStoreStateMachine.Event.OperationFailed); + objectInDataStoreMgr.update(destObj, ObjectInDataStoreStateMachine.Event.OperationFailed); } catch (NoTransitionException e1) { } - CreateCmdResult res = new CreateCmdResult( - null, null); + CreateCmdResult res = new CreateCmdResult(null, null); res.setResult("Failed to update copying state: " + e.toString()); context.getParentCallback().complete(res); } - CreateCmdResult res = new CreateCmdResult( - result.getPath(), null); + CreateCmdResult res = new CreateCmdResult(result.getPath(), null); context.getParentCallback().complete(res); return null; } - - class DeleteContext extends AsyncRpcConext { + class DeleteContext extends AsyncRpcConext { private final DataObject obj; + public DeleteContext(AsyncCompletionCallback callback, DataObject obj) { super(callback); this.obj = obj; } - + } + @Override - public void deleteAsync(DataObject data, - AsyncCompletionCallback callback) { + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { try { objectInDataStoreMgr.update(data, Event.DestroyRequested); } catch (NoTransitionException e) { s_logger.debug("destroy failed", e); - CreateCmdResult res = new CreateCmdResult( - null, null); + CreateCmdResult res = new CreateCmdResult(null, null); callback.complete(res); } - - DeleteContext context = new DeleteContext( - callback, data); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().deleteAsynCallback(null, null)) - .setContext(context); + + DeleteContext context = new DeleteContext(callback, data); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().deleteAsynCallback(null, null)).setContext(context); data.getDataStore().getDriver().deleteAsync(data, caller); return; } - + protected Void deleteAsynCallback(AsyncCallbackDispatcher callback, DeleteContext context) { DataObject destObj = context.obj; @@ -326,47 +287,44 @@ public class DataObjectManagerImpl implements DataObjectManager { try { objectInDataStoreMgr.update(destObj, Event.OperationFailed); } catch (NoTransitionException e) { - s_logger.debug("delete failed", e); + s_logger.debug("delete failed", e); } - + } else { try { objectInDataStoreMgr.update(destObj, Event.OperationSuccessed); } catch (NoTransitionException e) { - s_logger.debug("delete failed", e); + s_logger.debug("delete failed", e); } } - + context.getParentCallback().complete(res); return null; } @Override public DataObject createInternalStateOnly(DataObject data, DataStore store) { - DataObjectInStore obj = objectInDataStoreMgr.findObject( - data, store); + DataObjectInStore obj = objectInDataStoreMgr.findObject(data, store); DataObject objInStore = null; if (obj == null) { - objInStore = objectInDataStoreMgr.create( - data, store); + objInStore = objectInDataStoreMgr.create(data, store); } try { ObjectInDataStoreStateMachine.Event event = null; event = ObjectInDataStoreStateMachine.Event.CreateRequested; - objectInDataStoreMgr.update(objInStore, - event); - + objectInDataStoreMgr.update(objInStore, event); + objectInDataStoreMgr.update(objInStore, ObjectInDataStoreStateMachine.Event.OperationSuccessed); } catch (NoTransitionException e) { s_logger.debug("Failed to update state", e); throw new CloudRuntimeException("Failed to update state", e); } - + return objInStore; } @Override public void update(DataObject data, String path, Long size) { - throw new CloudRuntimeException("not implemented"); + throw new CloudRuntimeException("not implemented"); } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 0fdad7ce9f0..7120da175d0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -53,11 +53,12 @@ public class DataStoreManagerImpl implements DataStoreManager { } throw new CloudRuntimeException("un recognized type" + role); } + @Override - public DataStore registerDataStore(Map params, - String providerUuid) { + public DataStore registerDataStore(Map params, String providerUuid) { return null; } + @Override public DataStore getDataStore(String uuid, DataStoreRole role) { if (role == DataStoreRole.Primary) { @@ -68,15 +69,11 @@ public class DataStoreManagerImpl implements DataStoreManager { throw new CloudRuntimeException("un recognized type" + role); } - - @Override public List getImageStoresByScope(ZoneScope scope) { return imageDataStoreMgr.listImageStoresByScope(scope); } - - @Override public DataStore getImageStore(long zoneId) { List stores = getImageStoresByScope(new ZoneScope(zoneId)); @@ -96,14 +93,15 @@ public class DataStoreManagerImpl implements DataStoreManager { public DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); } + @Override public List getImageCacheStores(Scope scope) { - return imageDataStoreMgr.listImageCacheStores(scope); + return imageDataStoreMgr.listImageCacheStores(scope); } + @Override public List listImageStores() { return imageDataStoreMgr.listImageStores(); } - } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index f49929f2421..b72d07b2d88 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -27,11 +27,16 @@ import com.cloud.utils.fsm.NoTransitionException; public interface ObjectInDataStoreManager { public DataObject create(DataObject dataObj, DataStore dataStore); + public boolean delete(DataObject dataObj); + public DataObject get(DataObject dataObj, DataStore store); + public boolean update(DataObject vo, Event event) throws NoTransitionException; - DataObjectInStore findObject(long objId, DataObjectType type, - long dataStoreId, DataStoreRole role); + + DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role); + DataObjectInStore findObject(DataObject obj, DataStore store); - DataStore findStore(long objId, DataObjectType type, DataStoreRole role); + + DataStore findStore(long objId, DataObjectType type, DataStoreRole role); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index daeaf7cfd0a..4b3d4a622d5 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -23,14 +23,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; 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.ObjectInDataStoreStateMachine; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; @@ -39,7 +37,6 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.db.ObjectInDataStoreDao; -import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -52,17 +49,13 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.template.TemplateConstants; -import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.SearchCriteria2; -import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.fsm.StateMachine2; @Component public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { - private static final Logger s_logger = Logger - .getLogger(ObjectInDataStoreManagerImpl.class); + private static final Logger s_logger = Logger.getLogger(ObjectInDataStoreManagerImpl.class); @Inject TemplateDataFactory imageFactory; @Inject @@ -91,35 +84,25 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { public ObjectInDataStoreManagerImpl() { stateMachines = new StateMachine2(); - stateMachines.addTransition(State.Allocated, Event.CreateOnlyRequested, - State.Creating); - stateMachines.addTransition(State.Creating, Event.OperationFailed, - State.Allocated); - stateMachines.addTransition(State.Creating, Event.OperationSuccessed, - State.Ready); - stateMachines.addTransition(State.Ready, Event.CopyingRequested, - State.Copying); - stateMachines.addTransition(State.Copying, Event.OperationSuccessed, - State.Ready); - stateMachines.addTransition(State.Copying, Event.OperationFailed, - State.Ready); - stateMachines.addTransition(State.Ready, Event.DestroyRequested, - State.Destroying); - stateMachines.addTransition(State.Destroying, Event.DestroyRequested, - State.Destroying); - stateMachines.addTransition(State.Destroying, Event.OperationSuccessed, - State.Destroyed); - stateMachines.addTransition(State.Destroying, Event.OperationFailed, - State.Destroying); - //TODO: further investigate why an extra event is sent when it is alreay Ready for DownloadListener - stateMachines.addTransition(State.Ready, Event.OperationSuccessed, - State.Ready); + stateMachines.addTransition(State.Allocated, Event.CreateOnlyRequested, State.Creating); + stateMachines.addTransition(State.Creating, Event.OperationFailed, State.Allocated); + stateMachines.addTransition(State.Creating, Event.OperationSuccessed, State.Ready); + stateMachines.addTransition(State.Ready, Event.CopyingRequested, State.Copying); + stateMachines.addTransition(State.Copying, Event.OperationSuccessed, State.Ready); + stateMachines.addTransition(State.Copying, Event.OperationFailed, State.Ready); + stateMachines.addTransition(State.Ready, Event.DestroyRequested, State.Destroying); + stateMachines.addTransition(State.Destroying, Event.DestroyRequested, State.Destroying); + stateMachines.addTransition(State.Destroying, Event.OperationSuccessed, State.Destroyed); + stateMachines.addTransition(State.Destroying, Event.OperationFailed, State.Destroying); + // TODO: further investigate why an extra event is sent when it is + // alreay Ready for DownloadListener + stateMachines.addTransition(State.Ready, Event.OperationSuccessed, State.Ready); } @Override public DataObject create(DataObject obj, DataStore dataStore) { if (dataStore.getRole() == DataStoreRole.Primary) { - if ( obj.getType() == DataObjectType.TEMPLATE){ + if (obj.getType() == DataObjectType.TEMPLATE) { VMTemplateStoragePoolVO vo = new VMTemplateStoragePoolVO(dataStore.getId(), obj.getId()); vo = templatePoolDao.persist(vo); } else if (obj.getType() == DataObjectType.SNAPSHOT) { @@ -132,29 +115,40 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } } else { // Image store - switch ( obj.getType()){ + switch (obj.getType()) { case TEMPLATE: TemplateDataStoreVO ts = new TemplateDataStoreVO(); ts.setTemplateId(obj.getId()); ts.setDataStoreId(dataStore.getId()); ts.setDataStoreRole(dataStore.getRole()); - String installPath = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId(); - if ( dataStore.getTO() instanceof S3TO ){ - TemplateInfo tmpl = (TemplateInfo)obj; - installPath += "/" + tmpl.getUniqueName(); // for S3, we append template name in the path for template sync since we don't have template.properties there + String installPath = TemplateConstants.DEFAULT_TMPLT_ROOT_DIR + "/" + + TemplateConstants.DEFAULT_TMPLT_FIRST_LEVEL_DIR + + templateDao.findById(obj.getId()).getAccountId() + "/" + obj.getId(); + if (dataStore.getTO() instanceof S3TO) { + TemplateInfo tmpl = (TemplateInfo) obj; + installPath += "/" + tmpl.getUniqueName(); // for S3, we + // append + // template name + // in the path + // for template + // sync since we + // don't have + // template.properties + // there } ts.setInstallPath(installPath); ts.setState(ObjectInDataStoreStateMachine.State.Allocated); ts = templateDataStoreDao.persist(ts); break; case SNAPSHOT: - SnapshotInfo snapshot = (SnapshotInfo)obj; + SnapshotInfo snapshot = (SnapshotInfo) obj; SnapshotDataStoreVO ss = new SnapshotDataStoreVO(); ss.setSnapshotId(obj.getId()); ss.setDataStoreId(dataStore.getId()); ss.setRole(dataStore.getRole()); ss.setRole(dataStore.getRole()); - ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + snapshotDao.findById(obj.getId()).getAccountId() + "/" + snapshot.getVolumeId()); + ss.setInstallPath(TemplateConstants.DEFAULT_SNAPSHOT_ROOT_DIR + "/" + + snapshotDao.findById(obj.getId()).getAccountId() + "/" + snapshot.getVolumeId()); ss.setState(ObjectInDataStoreStateMachine.State.Allocated); ss = snapshotDataStoreDao.persist(ss); break; @@ -162,59 +156,61 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { VolumeDataStoreVO vs = new VolumeDataStoreVO(); vs.setVolumeId(obj.getId()); vs.setDataStoreId(dataStore.getId()); - vs.setInstallPath(TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + volumeDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); + vs.setInstallPath(TemplateConstants.DEFAULT_VOLUME_ROOT_DIR + "/" + + volumeDao.findById(obj.getId()).getAccountId() + "/" + obj.getId()); vs.setState(ObjectInDataStoreStateMachine.State.Allocated); vs = volumeDataStoreDao.persist(vs); break; } } - return this.get(obj, dataStore); + return this.get(obj, dataStore); } - @Override public boolean delete(DataObject dataObj) { long objId = dataObj.getId(); DataStore dataStore = dataObj.getDataStore(); if (dataStore.getRole() == DataStoreRole.Primary) { - if ( dataObj.getType() == DataObjectType.TEMPLATE){ + if (dataObj.getType() == DataObjectType.TEMPLATE) { VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId); - if ( destTmpltPool != null ){ + if (destTmpltPool != null) { return templatePoolDao.remove(destTmpltPool.getId()); } else { - s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + ", so no need to delete"); + s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + + ", so no need to delete"); return true; } } } else { // Image store - switch ( dataObj.getType()){ + switch (dataObj.getType()) { case TEMPLATE: TemplateDataStoreVO destTmpltStore = templateDataStoreDao.findByStoreTemplate(dataStore.getId(), objId); - if ( destTmpltStore != null ){ + if (destTmpltStore != null) { return templateDataStoreDao.remove(destTmpltStore.getId()); - } - else{ - s_logger.warn("Template " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + } else { + s_logger.warn("Template " + objId + " is not found on image store " + dataStore.getId() + + ", so no need to delete"); return true; } case SNAPSHOT: - SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), dataStore.getId(), objId); - if ( destSnapshotStore != null ){ + SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), + dataStore.getId(), objId); + if (destSnapshotStore != null) { return snapshotDataStoreDao.remove(destSnapshotStore.getId()); - } - else{ - s_logger.warn("Snapshot " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + } else { + s_logger.warn("Snapshot " + objId + " is not found on image store " + dataStore.getId() + + ", so no need to delete"); return true; } case VOLUME: VolumeDataStoreVO destVolumeStore = volumeDataStoreDao.findByStoreVolume(dataStore.getId(), objId); - if ( destVolumeStore != null ){ + if (destVolumeStore != null) { return volumeDataStoreDao.remove(destVolumeStore.getId()); - } - else{ - s_logger.warn("Volume " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + } else { + s_logger.warn("Volume " + objId + " is not found on image store " + dataStore.getId() + + ", so no need to delete"); return true; } } @@ -225,17 +221,15 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } @Override - public boolean update(DataObject data, Event event) - throws NoTransitionException { + public boolean update(DataObject data, Event event) throws NoTransitionException { DataObjectInStore obj = this.findObject(data, data.getDataStore()); if (obj == null) { - throw new CloudRuntimeException( - "can't find mapping in ObjectInDataStore table for: " - + data); + throw new CloudRuntimeException("can't find mapping in ObjectInDataStore table for: " + data); } - if ( data.getDataStore().getRole() == DataStoreRole.Image || data.getDataStore().getRole() == DataStoreRole.ImageCache){ - switch (data.getType()){ + if (data.getDataStore().getRole() == DataStoreRole.Image + || data.getDataStore().getRole() == DataStoreRole.ImageCache) { + switch (data.getType()) { case TEMPLATE: this.stateMachines.transitTo(obj, event, null, templateDataStoreDao); break; @@ -248,13 +242,13 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } } else if (data.getType() == DataObjectType.TEMPLATE && data.getDataStore().getRole() == DataStoreRole.Primary) { - this.stateMachines.transitTo(obj, event, null, - templatePoolDao); + this.stateMachines.transitTo(obj, event, null, templatePoolDao); } else if (data.getType() == DataObjectType.SNAPSHOT && data.getDataStore().getRole() == DataStoreRole.Primary) { this.stateMachines.transitTo(obj, event, null, snapshotDataStoreDao); } else { - throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + data.getDataStore().getRole()); + throw new CloudRuntimeException("Invalid data or store type: " + data.getType() + " " + + data.getDataStore().getRole()); } return true; } @@ -277,13 +271,11 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return findObject(obj.getId(), obj.getType(), store.getId(), store.getRole()); } - @Override - public DataObjectInStore findObject(long objId, DataObjectType type, - long dataStoreId, DataStoreRole role) { + public DataObjectInStore findObject(long objId, DataObjectType type, long dataStoreId, DataStoreRole role) { DataObjectInStore vo = null; if (role == DataStoreRole.Image || role == DataStoreRole.ImageCache) { - switch (type){ + switch (type) { case TEMPLATE: vo = templateDataStoreDao.findByStoreTemplate(dataStoreId, objId); break; @@ -308,11 +300,11 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { } @Override - public DataStore findStore(long objId, DataObjectType type, DataStoreRole role) { + public DataStore findStore(long objId, DataObjectType type, DataStoreRole role) { DataStore store = null; if (role == DataStoreRole.Image) { DataObjectInStore vo = null; - switch (type){ + switch (type) { case TEMPLATE: vo = templateDataStoreDao.findByTemplate(objId, role); break; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java index fdaaace49d7..d8b2a734792 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStore.java @@ -36,9 +36,8 @@ public interface PrimaryDataStore extends DataStore, PrimaryDataStoreInfo { boolean exists(DataObject data); TemplateInfo getTemplate(long templateId); - - SnapshotInfo getSnapshot(long snapshotId); + SnapshotInfo getSnapshot(long snapshotId); DiskFormat getDefaultDiskType(); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java index 2dc3e255b38..f62adfce999 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java @@ -31,11 +31,11 @@ import com.cloud.storage.StoragePoolStatus; public class PrimaryDataStoreEntityImpl implements StorageEntity { private PrimaryDataStoreInfo dataStore; - + public PrimaryDataStoreEntityImpl(PrimaryDataStoreInfo dataStore) { this.dataStore = dataStore; } - + @Override public boolean enable() { // TODO Auto-generated method stub @@ -72,7 +72,7 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { @Override public String getCurrentState() { - return null; + return null; } @Override @@ -105,7 +105,6 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { return null; } - @Override public void addDetail(String name, String value) { // TODO Auto-generated method stub @@ -132,7 +131,7 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { @Override public State getState() { - //return this.dataStore.getManagedState(); + // return this.dataStore.getManagedState(); return null; } @@ -230,17 +229,16 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { return null; } - public String getStorageType() { // TODO Auto-generated method stub return null; } - @Override - public void persist() { - // TODO Auto-generated method stub - - } + @Override + public void persist() { + // TODO Auto-generated method stub + + } @Override public boolean isInMaintenance() { diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java index b3ed0aaab68..8613668b180 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreProviderManager.java @@ -21,11 +21,12 @@ package org.apache.cloudstack.storage.datastore; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; - public interface PrimaryDataStoreProviderManager { public PrimaryDataStore getPrimaryDataStore(long dataStoreId); + public PrimaryDataStore getPrimaryDataStore(String uuid); boolean registerDriver(String providerName, PrimaryDataStoreDriver driver); + boolean registerHostListener(String providerName, HypervisorHostListener listener); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java index b0a7d50c57d..b27c96edbb7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/protocol/DataStoreProtocol.java @@ -17,14 +17,14 @@ package org.apache.cloudstack.storage.datastore.protocol; public enum DataStoreProtocol { - NFS("nfs"), - ISCSI("iscsi"); - + NFS("nfs"), ISCSI("iscsi"); + private String name; + DataStoreProtocol(String name) { this.name = name; } - + @Override public String toString() { return this.name; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index 796afe2d4df..db056e9e4c0 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -43,8 +43,7 @@ import com.cloud.utils.component.ManagerBase; @Component public class DataStoreProviderManagerImpl extends ManagerBase implements DataStoreProviderManager { - private static final Logger s_logger = Logger - .getLogger(DataStoreProviderManagerImpl.class); + private static final Logger s_logger = Logger.getLogger(DataStoreProviderManagerImpl.class); @Inject List providers; protected Map providerMap = new HashMap(); @@ -52,6 +51,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; @Inject ImageStoreProviderManager imageDataStoreProviderMgr; + @Override public DataStoreProvider getDataStoreProvider(String name) { return providerMap.get(name); @@ -103,14 +103,14 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } @Override - public boolean configure(String name, Map params) - throws ConfigurationException { + public boolean configure(String name, Map params) throws ConfigurationException { Map copyParams = new HashMap(params); for (DataStoreProvider provider : providers) { String providerName = provider.getName(); if (providerMap.get(providerName) != null) { - s_logger.debug("Failed to register data store provider, provider name: " + providerName + " is not unique"); + s_logger.debug("Failed to register data store provider, provider name: " + providerName + + " is not unique"); return false; } @@ -127,13 +127,14 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto Set types = provider.getTypes(); if (types.contains(DataStoreProviderType.PRIMARY)) { - primaryDataStoreProviderMgr.registerDriver(provider.getName(), (PrimaryDataStoreDriver)provider.getDataStoreDriver()); + primaryDataStoreProviderMgr.registerDriver(provider.getName(), + (PrimaryDataStoreDriver) provider.getDataStoreDriver()); primaryDataStoreProviderMgr.registerHostListener(provider.getName(), provider.getHostListener()); + } else if (types.contains(DataStoreProviderType.IMAGE)) { + imageDataStoreProviderMgr.registerDriver(provider.getName(), + (ImageStoreDriver) provider.getDataStoreDriver()); } - else if (types.contains(DataStoreProviderType.IMAGE)) { - imageDataStoreProviderMgr.registerDriver(provider.getName(), (ImageStoreDriver)provider.getDataStoreDriver()); - } - } catch(Exception e) { + } catch (Exception e) { s_logger.debug("configure provider failed", e); providerMap.remove(providerName); return false; @@ -148,7 +149,6 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return this.getDataStoreProvider(DataStoreProvider.DEFAULT_PRIMARY); } - @Override public DataStoreProvider getDefaultImageDataStoreProvider() { return this.getDataStoreProvider(DataStoreProvider.NFS_IMAGE); @@ -169,7 +169,7 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.IMAGE.toString())) { return this.getImageDataStoreProviders(); } else if (type.equalsIgnoreCase(DataStoreProvider.DataStoreProviderType.ImageCache.toString())) { - return this.getCacheDataStoreProviders(); + return this.getCacheDataStoreProviders(); } else { throw new InvalidParameterValueException("Invalid parameter: " + type); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java index fb7dec0fa41..37d089d816d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDao.java @@ -22,6 +22,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface ObjectInDataStoreDao extends GenericDao, StateDao { +public interface ObjectInDataStoreDao extends GenericDao, + StateDao { } diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java index 9965d60b23d..aac1d134e34 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreDaoImpl.java @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.db; + import java.util.Date; import java.util.Map; @@ -36,10 +37,11 @@ import com.cloud.utils.db.UpdateBuilder; public class ObjectInDataStoreDaoImpl extends GenericDaoBase implements ObjectInDataStoreDao { private static final Logger s_logger = Logger.getLogger(ObjectInDataStoreDaoImpl.class); private SearchBuilder updateStateSearch; + @Override public boolean configure(String name, Map params) throws ConfigurationException { - super.configure(name, params); - + super.configure(name, params); + updateStateSearch = this.createSearchBuilder(); updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); @@ -47,14 +49,13 @@ public class ObjectInDataStoreDaoImpl extends GenericDaoBase sc = updateStateSearch.create(); sc.setParameters("id", vo.getId()); sc.setParameters("state", currentState); @@ -66,19 +67,23 @@ public class ObjectInDataStoreDaoImpl extends GenericDaoBase 0; diff --git a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java index ecf03913c3e..df9c83641f6 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/db/ObjectInDataStoreVO.java @@ -78,13 +78,13 @@ public class ObjectInDataStoreVO implements StateObject listUpAndConnectingSecondaryStorageVmHost(Long dcId) { @@ -223,16 +218,17 @@ public class DefaultEndPointSelector implements EndPointSelector { return select(store); } - @Override public EndPoint select(DataStore store) { if (store.getRole() == DataStoreRole.Primary) { return findEndpointForPrimaryStorage(store); } else if (store.getRole() == DataStoreRole.Image) { - //in case there is no ssvm, directly send down command hypervisor host - // otherwise, send to localhost for bootstrap system vm template download + // in case there is no ssvm, directly send down command hypervisor + // host + // otherwise, send to localhost for bootstrap system vm template + // download return findEndpointForImageStorage(store); - }else { + } else { throw new CloudRuntimeException("not implemented yet"); } } @@ -242,16 +238,16 @@ public class DefaultEndPointSelector implements EndPointSelector { List endPoints = new ArrayList(); if (store.getScope().getScopeType() == ScopeType.HOST) { HostVO host = hostDao.findById(store.getScope().getScopeId()); - endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress(), host.getPublicIpAddress())); + endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), + host.getPublicIpAddress())); } else if (store.getScope().getScopeType() == ScopeType.CLUSTER) { SearchCriteriaService sc = SearchCriteria2.create(HostVO.class); sc.addAnd(sc.getEntity().getClusterId(), Op.EQ, store.getScope().getScopeId()); sc.addAnd(sc.getEntity().getStatus(), Op.EQ, Status.Up); List hosts = sc.find(); for (HostVO host : hosts) { - endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), - host.getPrivateIpAddress(), host.getPublicIpAddress())); + endPoints.add(RemoteHostEndPoint.getHypervisorHostEndPoint(host.getId(), host.getPrivateIpAddress(), + host.getPublicIpAddress())); } } else { diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java index 51c8c439fc2..a8d94725175 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java @@ -39,7 +39,7 @@ public class TemplateEntityImpl implements TemplateEntity { } public ImageStoreInfo getImageDataStore() { - return (ImageStoreInfo)templateInfo.getDataStore(); + return (ImageStoreInfo) templateInfo.getDataStore(); } public long getImageDataStoreId() { @@ -57,7 +57,7 @@ public class TemplateEntityImpl implements TemplateEntity { @Override public long getId() { - return this.templateInfo.getId(); + return this.templateInfo.getId(); } public String getExternalId() { @@ -101,7 +101,6 @@ public class TemplateEntityImpl implements TemplateEntity { return null; } - @Override public void addDetail(String name, String value) { // TODO Auto-generated method stub diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java index deb702f3571..a2d61f91fbe 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreHelper.java @@ -31,7 +31,6 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; -import com.cloud.storage.ImageStore; import com.cloud.storage.ScopeType; import com.cloud.utils.exception.CloudRuntimeException; @@ -43,59 +42,59 @@ public class ImageStoreHelper { ImageStoreDetailsDao imageStoreDetailsDao; public ImageStoreVO createImageStore(Map params) { - ImageStoreVO store = imageStoreDao.findByName((String)params.get("name")); + ImageStoreVO store = imageStoreDao.findByName((String) params.get("name")); if (store != null) { return store; } store = new ImageStoreVO(); - store.setProtocol((String)params.get("protocol")); - store.setProviderName((String)params.get("providerName")); - store.setScope((ScopeType)params.get("scope")); - store.setDataCenterId((Long)params.get("zoneId")); - String uuid = (String)params.get("uuid"); + store.setProtocol((String) params.get("protocol")); + store.setProviderName((String) params.get("providerName")); + store.setScope((ScopeType) params.get("scope")); + store.setDataCenterId((Long) params.get("zoneId")); + String uuid = (String) params.get("uuid"); if (uuid != null) { store.setUuid(uuid); } else { store.setUuid(UUID.randomUUID().toString()); } - store.setName((String)params.get("name")); - if ( store.getName() == null ){ + store.setName((String) params.get("name")); + if (store.getName() == null) { store.setName(store.getUuid()); } - store.setUrl((String)params.get("url")); - store.setRole((DataStoreRole)params.get("role")); + store.setUrl((String) params.get("url")); + store.setRole((DataStoreRole) params.get("role")); store = imageStoreDao.persist(store); return store; } public ImageStoreVO createImageStore(Map params, Map details) { - ImageStoreVO store = imageStoreDao.findByName((String)params.get("name")); + ImageStoreVO store = imageStoreDao.findByName((String) params.get("name")); if (store != null) { return store; } store = new ImageStoreVO(); - store.setProtocol((String)params.get("protocol")); - store.setProviderName((String)params.get("providerName")); - store.setScope((ScopeType)params.get("scope")); - store.setDataCenterId((Long)params.get("zoneId")); - String uuid = (String)params.get("uuid"); + store.setProtocol((String) params.get("protocol")); + store.setProviderName((String) params.get("providerName")); + store.setScope((ScopeType) params.get("scope")); + store.setDataCenterId((Long) params.get("zoneId")); + String uuid = (String) params.get("uuid"); if (uuid != null) { store.setUuid(uuid); } else { store.setUuid(UUID.randomUUID().toString()); } - store.setUrl((String)params.get("url")); - store.setName((String)params.get("name")); - if ( store.getName() == null ){ + store.setUrl((String) params.get("url")); + store.setName((String) params.get("name")); + if (store.getName() == null) { store.setName(store.getUuid()); } - store.setRole((DataStoreRole)params.get("role")); + store.setRole((DataStoreRole) params.get("role")); store = imageStoreDao.persist(store); // persist details - if (details != null){ + if (details != null) { Iterator keyIter = details.keySet().iterator(); - while (keyIter.hasNext()){ + while (keyIter.hasNext()) { String key = keyIter.next(); ImageStoreDetailVO detail = new ImageStoreDetailVO(); detail.setStoreId(store.getId()); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java index f8fa28176a0..be66cc51401 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/datastore/ImageStoreProviderManager.java @@ -27,10 +27,16 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; public interface ImageStoreProviderManager { ImageStoreEntity getImageStore(long dataStoreId); + ImageStoreEntity getImageStore(String uuid); + List listImageStores(); + List listImageStoresByScope(ZoneScope scope); + List listImageStoreByProvider(String provider); + List listImageCacheStores(Scope scope); + boolean registerDriver(String uuid, ImageStoreDriver driver); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java index 70316b9ee1c..acbbc7d74a8 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDaoImpl.java @@ -23,12 +23,9 @@ import java.util.Map; import javax.naming.ConfigurationException; - -import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; -import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.storage.DataStoreRole; @@ -39,12 +36,9 @@ import com.cloud.utils.db.SearchCriteria; @Component public class ImageStoreDaoImpl extends GenericDaoBase implements ImageStoreDao { - - private static final Logger s_logger = Logger.getLogger(ImageStoreDaoImpl.class); private SearchBuilder nameSearch; private SearchBuilder providerSearch; - @Override public boolean configure(String name, Map params) throws ConfigurationException { super.configure(name, params); @@ -87,7 +81,8 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem scc.addOr("dcId", SearchCriteria.Op.EQ, scope.getScopeId()); sc.addAnd("scope", SearchCriteria.Op.SC, scc); } - // we should return all image stores if cross-zone scope is passed (scopeId = null) + // we should return all image stores if cross-zone scope is passed + // (scopeId = null) return listBy(sc); } @@ -109,5 +104,4 @@ public class ImageStoreDaoImpl extends GenericDaoBase implem return listBy(sc); } - } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java index 8f711c686de..ad52042bc7c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/ImageStoreDetailsDaoImpl.java @@ -26,14 +26,13 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailVO; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.springframework.stereotype.Component; -import com.cloud.host.DetailVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @Component -@Local(value=ImageStoreDetailsDao.class) +@Local(value = ImageStoreDetailsDao.class) public class ImageStoreDetailsDaoImpl extends GenericDaoBase implements ImageStoreDetailsDao { protected final SearchBuilder storeSearch; @@ -62,16 +61,16 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase getDetails(long storeId) { - SearchCriteria sc = storeSearch.create(); - sc.setParameters("store", storeId); + SearchCriteria sc = storeSearch.create(); + sc.setParameters("store", storeId); - List details = listBy(sc); - Map detailsMap = new HashMap(); - for (ImageStoreDetailVO detail : details) { - detailsMap.put(detail.getName(), detail.getValue()); - } + List details = listBy(sc); + Map detailsMap = new HashMap(); + for (ImageStoreDetailVO detail : details) { + detailsMap.put(detail.getName(), detail.getValue()); + } - return detailsMap; + return detailsMap; } @Override @@ -86,5 +85,4 @@ public class ImageStoreDetailsDaoImpl extends GenericDaoBase params) throws ConfigurationException { - super.configure(name, params); + super.configure(name, params); storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); @@ -85,13 +84,11 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase sc = updateStateSearch.create(); sc.setParameters("id", dataObj.getId()); sc.setParameters("state", currentState); @@ -108,20 +105,23 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase 0; } - @Override public List listByStoreId(long id, DataStoreRole role) { SearchCriteria sc = storeSearch.create(); @@ -157,8 +157,6 @@ public class SnapshotDataStoreDaoImpl extends GenericDaoBase listDestroyed(long id) { SearchCriteria sc = destroyedSearch.create(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java index a90a2f620e0..362f7a6aa96 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.image.db; + import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -34,7 +35,6 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import com.cloud.storage.DataStoreRole; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDaoBase; @@ -57,13 +57,12 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase storeTemplateStateSearch; private SearchBuilder storeTemplateDownloadStatusSearch; - - @Inject private DataStoreManager _storeMgr; + @Inject + private DataStoreManager _storeMgr; @Override public boolean configure(String name, Map params) throws ConfigurationException { - super.configure(name, params); - + super.configure(name, params); storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); @@ -81,8 +80,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = updateStateSearch.create(); sc.setParameters("id", dataObj.getId()); sc.setParameters("state", currentState); @@ -136,7 +138,7 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase 0; } - @Override public List listByStoreId(long id) { SearchCriteria sc = storeSearch.create(); @@ -209,33 +214,31 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = storeTemplateStateSearch.create(); sc.setParameters("template_id", templateId); sc.setParameters("store_id", storeId); - sc.setParameters("states", (Object[])states); + sc.setParameters("states", (Object[]) states); sc.setParameters("destroyed", false); return search(sc, null); } - - @Override public List listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) { SearchCriteria sc = storeTemplateDownloadStatusSearch.create(); sc.setParameters("template_id", templateId); sc.setParameters("store_id", storeId); - sc.setParameters("downloadState", (Object[])status); + sc.setParameters("downloadState", (Object[]) status); sc.setParameters("destroyed", false); return search(sc, null); } - @Override public List listByTemplateZoneDownloadStatus(long templateId, Long zoneId, Status... status) { // get all elgible image stores List imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); - if ( imgStores != null ){ + if (imgStores != null) { List result = new ArrayList(); - for (DataStore store : imgStores){ - List sRes = this.listByTemplateStoreDownloadStatus(templateId, store.getId(), status); - if ( sRes != null && sRes.size() > 0){ + for (DataStore store : imgStores) { + List sRes = this.listByTemplateStoreDownloadStatus(templateId, store.getId(), + status); + if (sRes != null && sRes.size() > 0) { result.addAll(sRes); } } @@ -244,15 +247,15 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); - if ( imgStores != null ){ - for (DataStore store : imgStores){ - List sRes = this.listByTemplateStoreDownloadStatus(templateId, store.getId(), status); - if ( sRes != null && sRes.size() > 0){ + if (imgStores != null) { + for (DataStore store : imgStores) { + List sRes = this.listByTemplateStoreDownloadStatus(templateId, store.getId(), + status); + if (sRes != null && sRes.size() > 0) { Collections.shuffle(sRes); return sRes.get(0); } @@ -270,7 +273,6 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = storeTemplateSearch.create(); @@ -283,7 +285,6 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase sc = templateRoleSearch.create(); @@ -305,15 +306,15 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase imgStores = null; - if ( role == DataStoreRole.Image){ + if (role == DataStoreRole.Image) { imgStores = this._storeMgr.getImageStoresByScope(new ZoneScope(zoneId)); - } else if (role == DataStoreRole.ImageCache){ + } else if (role == DataStoreRole.ImageCache) { imgStores = this._storeMgr.getImageCacheStores(new ZoneScope(zoneId)); } - if ( imgStores != null ){ - for (DataStore store : imgStores){ + if (imgStores != null) { + for (DataStore store : imgStores) { List sRes = this.listByTemplateStore(templateId, store.getId()); - if ( sRes != null && sRes.size() > 0){ + if (sRes != null && sRes.size() > 0) { return sRes.get(0); } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java index 96cfc91bb43..56020720914 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.image.db; + import java.util.Date; import java.util.List; import java.util.Map; @@ -24,14 +25,11 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State; -import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.storage.VolumeHostVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -49,8 +47,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase params) throws ConfigurationException { - super.configure(name, params); - + super.configure(name, params); storeSearch = createSearchBuilder(); storeSearch.and("store_id", storeSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ); @@ -75,14 +72,13 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase sc = updateStateSearch.create(); sc.setParameters("id", dataObj.getId()); sc.setParameters("state", currentState); @@ -93,7 +89,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase 0; } - @Override public List listByStoreId(long id) { SearchCriteria sc = storeSearch.create(); @@ -134,7 +133,6 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase sc = volumeSearch.create(); diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java index b37641300ed..b00e95d4d7d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/motion/ImageMotionService.java @@ -21,10 +21,10 @@ package org.apache.cloudstack.storage.image.motion; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.db.ObjectInDataStoreVO; -import org.apache.cloudstack.storage.volume.TemplateOnPrimaryDataStoreInfo; public interface ImageMotionService { - void copyTemplateAsync(TemplateInfo destTemplate, TemplateInfo srcTemplate, AsyncCompletionCallback callback); + void copyTemplateAsync(TemplateInfo destTemplate, TemplateInfo srcTemplate, + AsyncCompletionCallback callback); + boolean copyIso(String isoUri, String destIsoUri); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java index a59e5947a18..fb3ec48d744 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/snapshot/SnapshotEntityImpl.java @@ -27,160 +27,160 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; public class SnapshotEntityImpl implements SnapshotEntity { - @Override - public String getUuid() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getUuid() { + // TODO Auto-generated method stub + return null; + } - @Override - public long getId() { - // TODO Auto-generated method stub - return 0; - } + @Override + public long getId() { + // TODO Auto-generated method stub + return 0; + } - @Override - public String getCurrentState() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getCurrentState() { + // TODO Auto-generated method stub + return null; + } - @Override - public String getDesiredState() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getDesiredState() { + // TODO Auto-generated method stub + return null; + } - @Override - public Date getCreatedTime() { - // TODO Auto-generated method stub - return null; - } + @Override + public Date getCreatedTime() { + // TODO Auto-generated method stub + return null; + } - @Override - public Date getLastUpdatedTime() { - // TODO Auto-generated method stub - return null; - } + @Override + public Date getLastUpdatedTime() { + // TODO Auto-generated method stub + return null; + } - @Override - public String getOwner() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getOwner() { + // TODO Auto-generated method stub + return null; + } - @Override - public List getApplicableActions() { - // TODO Auto-generated method stub - return null; - } + @Override + public List getApplicableActions() { + // TODO Auto-generated method stub + return null; + } - @Override - public long getAccountId() { - // TODO Auto-generated method stub - return 0; - } + @Override + public long getAccountId() { + // TODO Auto-generated method stub + return 0; + } - @Override - public long getVolumeId() { - // TODO Auto-generated method stub - return 0; - } + @Override + public long getVolumeId() { + // TODO Auto-generated method stub + return 0; + } - @Override - public String getName() { - // TODO Auto-generated method stub - return null; - } + @Override + public String getName() { + // TODO Auto-generated method stub + return null; + } - @Override - public Date getCreated() { - // TODO Auto-generated method stub - return null; - } + @Override + public Date getCreated() { + // TODO Auto-generated method stub + return null; + } - @Override - public HypervisorType getHypervisorType() { - // TODO Auto-generated method stub - return null; - } + @Override + public HypervisorType getHypervisorType() { + // TODO Auto-generated method stub + return null; + } - @Override - public boolean isRecursive() { - // TODO Auto-generated method stub - return false; - } + @Override + public boolean isRecursive() { + // TODO Auto-generated method stub + return false; + } - @Override - public short getsnapshotType() { - // TODO Auto-generated method stub - return 0; - } + @Override + public short getsnapshotType() { + // TODO Auto-generated method stub + return 0; + } - @Override - public long getDomainId() { - // TODO Auto-generated method stub - return 0; - } + @Override + public long getDomainId() { + // TODO Auto-generated method stub + return 0; + } - @Override - public String reserveForBackup(int expiration) { - // TODO Auto-generated method stub - return null; - } + @Override + public String reserveForBackup(int expiration) { + // TODO Auto-generated method stub + return null; + } - @Override - public void backup(String reservationToken) { - // TODO Auto-generated method stub + @Override + public void backup(String reservationToken) { + // TODO Auto-generated method stub - } + } - @Override - public void restore(String vm) { - // TODO Auto-generated method stub + @Override + public void restore(String vm) { + // TODO Auto-generated method stub - } + } - @Override - public void destroy() { - // TODO Auto-generated method stub + @Override + public void destroy() { + // TODO Auto-generated method stub - } + } - @Override - public Map getDetails() { - // TODO Auto-generated method stub - return null; - } + @Override + public Map getDetails() { + // TODO Auto-generated method stub + return null; + } - @Override - public void addDetail(String name, String value) { - // TODO Auto-generated method stub - - } + @Override + public void addDetail(String name, String value) { + // TODO Auto-generated method stub - @Override - public void delDetail(String name, String value) { - // TODO Auto-generated method stub - - } + } - @Override - public void updateDetail(String name, String value) { - // TODO Auto-generated method stub - - } + @Override + public void delDetail(String name, String value) { + // TODO Auto-generated method stub - @Override - public State getState() { - // TODO Auto-generated method stub - return null; - } + } - @Override - public Type getRecurringType() { - // TODO Auto-generated method stub - return null; - } + @Override + public void updateDetail(String name, String value) { + // TODO Auto-generated method stub + + } + + @Override + public State getState() { + // TODO Auto-generated method stub + return null; + } + + @Override + public Type getRecurringType() { + // TODO Auto-generated method stub + return null; + } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java index d131008d65e..501f0447cb7 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java @@ -27,34 +27,27 @@ 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.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreParameters; -import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; 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.DeleteStoragePoolCommand; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.alert.AlertManager; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolHostVO; import com.cloud.storage.StoragePoolStatus; import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; @Component public class PrimaryDataStoreHelper { - private static final Logger s_logger = Logger - .getLogger(PrimaryDataStoreHelper.class); + private static final Logger s_logger = Logger.getLogger(PrimaryDataStoreHelper.class); @Inject private PrimaryDataStoreDao dataStoreDao; @Inject @@ -65,12 +58,13 @@ public class PrimaryDataStoreHelper { protected CapacityDao _capacityDao; @Inject protected StoragePoolHostDao storagePoolHostDao; + public DataStore createPrimaryDataStore(PrimaryDataStoreParameters params) { StoragePoolVO dataStoreVO = dataStoreDao.findPoolByUUID(params.getUuid()); if (dataStoreVO != null) { throw new CloudRuntimeException("duplicate uuid: " + params.getUuid()); } - + dataStoreVO = new StoragePoolVO(); dataStoreVO.setStorageProviderName(params.getProviderName()); dataStoreVO.setHostAddress(params.getHost()); @@ -84,7 +78,7 @@ public class PrimaryDataStoreHelper { dataStoreVO.setClusterId(params.getClusterId()); dataStoreVO.setStatus(StoragePoolStatus.Initialized); dataStoreVO.setUserInfo(params.getUserInfo()); - + Map details = params.getDetails(); String tags = params.getTags(); if (tags != null) { @@ -98,40 +92,41 @@ public class PrimaryDataStoreHelper { details.put(tag, "true"); } } - + dataStoreVO = dataStoreDao.persist(dataStoreVO, details); return dataStoreMgr.getDataStore(dataStoreVO.getId(), DataStoreRole.Primary); } - + public DataStore attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { StoragePoolHostVO poolHost = storagePoolHostDao.findByPoolHost(store.getId(), scope.getScopeId()); if (poolHost == null) { poolHost = new StoragePoolHostVO(store.getId(), scope.getScopeId(), existingInfo.getLocalPath()); storagePoolHostDao.persist(poolHost); } - + StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); pool.setScope(scope.getScopeType()); pool.setAvailableBytes(existingInfo.getAvailableBytes()); pool.setCapacityBytes(existingInfo.getCapacityBytes()); pool.setStatus(StoragePoolStatus.Up); this.dataStoreDao.update(pool.getId(), pool); - this.storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, pool.getCapacityBytes() - pool.getAvailableBytes()); + this.storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, + pool.getCapacityBytes() - pool.getAvailableBytes()); return dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); } - + public DataStore attachCluster(DataStore store) { StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); - + storageMgr.createCapacityEntry(pool.getId()); - + pool.setScope(ScopeType.CLUSTER); pool.setStatus(StoragePoolStatus.Up); this.dataStoreDao.update(pool.getId(), pool); return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); } - + public DataStore attachZone(DataStore store) { StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); pool.setScope(ScopeType.ZONE); @@ -139,27 +134,24 @@ public class PrimaryDataStoreHelper { this.dataStoreDao.update(pool.getId(), pool); return dataStoreMgr.getDataStore(store.getId(), DataStoreRole.Primary); } - + public boolean maintain(DataStore store) { StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); pool.setStatus(StoragePoolStatus.Maintenance); this.dataStoreDao.update(pool.getId(), pool); return true; } - + public boolean cancelMaintain(DataStore store) { StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); pool.setStatus(StoragePoolStatus.Up); dataStoreDao.update(store.getId(), pool); return true; } - protected boolean deletePoolStats(Long poolId) { - CapacityVO capacity1 = _capacityDao.findByHostIdType(poolId, - CapacityVO.CAPACITY_TYPE_STORAGE); - CapacityVO capacity2 = _capacityDao.findByHostIdType(poolId, - CapacityVO.CAPACITY_TYPE_STORAGE_ALLOCATED); + CapacityVO capacity1 = _capacityDao.findByHostIdType(poolId, Capacity.CAPACITY_TYPE_STORAGE); + CapacityVO capacity2 = _capacityDao.findByHostIdType(poolId, Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED); if (capacity1 != null) { _capacityDao.remove(capacity1.getId()); } @@ -167,31 +159,27 @@ public class PrimaryDataStoreHelper { if (capacity2 != null) { _capacityDao.remove(capacity2.getId()); } - + return true; } - + public boolean deletePrimaryDataStore(DataStore store) { - List hostPoolRecords = this.storagePoolHostDao - .listByPoolId(store.getId()); + List hostPoolRecords = this.storagePoolHostDao.listByPoolId(store.getId()); StoragePoolVO poolVO = this.dataStoreDao.findById(store.getId()); Transaction txn = Transaction.currentTxn(); txn.start(); for (StoragePoolHostVO host : hostPoolRecords) { - storagePoolHostDao.deleteStoragePoolHostDetails( - host.getHostId(), host.getPoolId()); + storagePoolHostDao.deleteStoragePoolHostDetails(host.getHostId(), host.getPoolId()); } poolVO.setUuid(null); this.dataStoreDao.update(poolVO.getId(), poolVO); dataStoreDao.remove(poolVO.getId()); deletePoolStats(poolVO.getId()); // Delete op_host_capacity entries - this._capacityDao.removeBy(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, - null, null, null, poolVO.getId()); + this._capacityDao.removeBy(Capacity.CAPACITY_TYPE_STORAGE_ALLOCATED, null, null, null, poolVO.getId()); txn.commit(); - s_logger.debug("Storage pool id=" + poolVO.getId() - + " is removed successfully"); + s_logger.debug("Storage pool id=" + poolVO.getId() + " is removed successfully"); return true; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java index b0a387a0fbb..9d174348c73 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/PrimaryDataStoreDetailsDaoImpl.java @@ -30,25 +30,25 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; @Component -public class PrimaryDataStoreDetailsDaoImpl extends GenericDaoBase implements PrimaryDataStoreDetailsDao { - +public class PrimaryDataStoreDetailsDaoImpl extends GenericDaoBase implements + PrimaryDataStoreDetailsDao { + protected final SearchBuilder PoolSearch = null; - + protected PrimaryDataStoreDetailsDaoImpl() { /* - super(); - PoolSearch = createSearchBuilder(); - PoolSearch.and("pool", PoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ); - PoolSearch.done(); - */ + * super(); PoolSearch = createSearchBuilder(); PoolSearch.and("pool", + * PoolSearch.entity().getPoolId(), SearchCriteria.Op.EQ); + * PoolSearch.done(); + */ } - + @Override public void update(long poolId, Map details) { Transaction txn = Transaction.currentTxn(); SearchCriteria sc = PoolSearch.create(); sc.setParameters("pool", poolId); - + txn.start(); expunge(sc); for (Map.Entry entry : details.entrySet()) { @@ -57,18 +57,18 @@ public class PrimaryDataStoreDetailsDaoImpl extends GenericDaoBase getDetails(long poolId) { - SearchCriteria sc = PoolSearch.create(); - sc.setParameters("pool", poolId); - - List details = listBy(sc); - Map detailsMap = new HashMap(); - for (PrimaryDataStoreDetailVO detail : details) { - detailsMap.put(detail.getName(), detail.getValue()); - } - - return detailsMap; + SearchCriteria sc = PoolSearch.create(); + sc.setParameters("pool", poolId); + + List details = listBy(sc); + Map detailsMap = new HashMap(); + for (PrimaryDataStoreDetailVO detail : details) { + detailsMap.put(detail.getName(), detail.getValue()); + } + + return detailsMap; } } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java index 63cdb16c596..1827edfe861 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDao.java @@ -23,7 +23,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState import com.cloud.utils.db.GenericDao; import com.cloud.utils.fsm.StateDao; -public interface TemplatePrimaryDataStoreDao extends GenericDao, StateDao { +public interface TemplatePrimaryDataStoreDao extends GenericDao, + StateDao { public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolId(long templateId, long poolId); + public TemplatePrimaryDataStoreVO findByTemplateIdAndPoolIdAndReady(long templateId, long poolId); } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java index ad561502266..7c986403636 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreDaoImpl.java @@ -35,9 +35,11 @@ import com.cloud.utils.db.SearchCriteriaService; import com.cloud.utils.db.UpdateBuilder; @Component -public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase implements TemplatePrimaryDataStoreDao { +public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase implements + TemplatePrimaryDataStoreDao { private static final Logger s_logger = Logger.getLogger(TemplatePrimaryDataStoreDaoImpl.class); protected final SearchBuilder updateSearchBuilder; + public TemplatePrimaryDataStoreDaoImpl() { updateSearchBuilder = createSearchBuilder(); updateSearchBuilder.and("id", updateSearchBuilder.entity().getId(), Op.EQ); @@ -45,9 +47,11 @@ public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class); + SearchCriteriaService sc = SearchCriteria2 + .create(TemplatePrimaryDataStoreVO.class); sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, templateId); sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId); return sc.find(); @@ -55,7 +59,8 @@ public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase sc = SearchCriteria2.create(TemplatePrimaryDataStoreVO.class); + SearchCriteriaService sc = SearchCriteria2 + .create(TemplatePrimaryDataStoreVO.class); sc.addAnd(sc.getEntity().getTemplateId(), Op.EQ, templateId); sc.addAnd(sc.getEntity().getPoolId(), Op.EQ, poolId); sc.addAnd(sc.getEntity().getState(), Op.EQ, ObjectInDataStoreStateMachine.State.Ready); @@ -63,34 +68,42 @@ public class TemplatePrimaryDataStoreDaoImpl extends GenericDaoBase 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((TemplatePrimaryDataStoreVO)vo, sc); + + int rows = update(vo, sc); if (rows == 0 && s_logger.isDebugEnabled()) { - TemplatePrimaryDataStoreVO template = findByIdIncludingRemoved(vo.getId()); + 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); + 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"); + s_logger.debug("Unable to update template: id=" + vo.getId() + + ", as there is no such template exists in the database anymore"); } } return rows > 0; } - + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java index 48a9f334a19..44765ed40a3 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/db/TemplatePrimaryDataStoreVO.java @@ -82,22 +82,22 @@ public class TemplatePrimaryDataStoreVO implements StateObject driverMaps; - @Inject StorageManager storageMgr; + @Inject + StorageManager storageMgr; @PostConstruct public void config() { @@ -56,7 +57,8 @@ public class PrimaryDataStoreProviderManagerImpl implements PrimaryDataStoreProv StoragePoolVO dataStoreVO = dataStoreDao.findById(dataStoreId); String providerName = dataStoreVO.getStorageProviderName(); DataStoreProvider provider = providerManager.getDataStoreProvider(providerName); - PrimaryDataStoreImpl dataStore = PrimaryDataStoreImpl.createDataStore(dataStoreVO, driverMaps.get(provider.getName()), provider); + PrimaryDataStoreImpl dataStore = PrimaryDataStoreImpl.createDataStore(dataStoreVO, + driverMaps.get(provider.getName()), provider); return dataStore; } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index 2c3ab9969a0..6431308ff74 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -38,16 +38,21 @@ import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.utils.exception.CloudRuntimeException; public class DefaultHostListener implements HypervisorHostListener { - private static final Logger s_logger = Logger - .getLogger(DefaultHostListener.class); - @Inject AgentManager agentMgr; - @Inject DataStoreManager dataStoreMgr; - @Inject AlertManager alertMgr; - @Inject StoragePoolHostDao storagePoolHostDao; - @Inject PrimaryDataStoreDao primaryStoreDao; + private static final Logger s_logger = Logger.getLogger(DefaultHostListener.class); + @Inject + AgentManager agentMgr; + @Inject + DataStoreManager dataStoreMgr; + @Inject + AlertManager alertMgr; + @Inject + StoragePoolHostDao storagePoolHostDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + @Override public boolean hostConnect(long hostId, long poolId) { - StoragePool pool = (StoragePool)this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); + StoragePool pool = (StoragePool) this.dataStoreMgr.getDataStore(poolId, DataStoreRole.Primary); ModifyStoragePoolCommand cmd = new ModifyStoragePoolCommand(true, pool); final Answer answer = agentMgr.easySend(hostId, cmd); @@ -58,20 +63,23 @@ public class DefaultHostListener implements HypervisorHostListener { if (!answer.getResult()) { String msg = "Unable to attach storage pool" + poolId + " to the host" + hostId; alertMgr.sendAlert(AlertManager.ALERT_TYPE_HOST, pool.getDataCenterId(), pool.getPodId(), msg, msg); - throw new CloudRuntimeException("Unable establish connection from storage head to storage pool " + pool.getId() + " due to " + answer.getDetails() + pool.getId()); + throw new CloudRuntimeException("Unable establish connection from storage head to storage pool " + + pool.getId() + " due to " + answer.getDetails() + pool.getId()); } - assert (answer instanceof ModifyStoragePoolAnswer) : "Well, now why won't you actually return the ModifyStoragePoolAnswer when it's ModifyStoragePoolCommand? Pool=" + pool.getId() + "Host=" + hostId; + assert (answer instanceof ModifyStoragePoolAnswer) : "Well, now why won't you actually return the ModifyStoragePoolAnswer when it's ModifyStoragePoolCommand? Pool=" + + pool.getId() + "Host=" + hostId; ModifyStoragePoolAnswer mspAnswer = (ModifyStoragePoolAnswer) answer; StoragePoolHostVO poolHost = storagePoolHostDao.findByPoolHost(pool.getId(), hostId); if (poolHost == null) { - poolHost = new StoragePoolHostVO(pool.getId(), hostId, mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/")); + poolHost = new StoragePoolHostVO(pool.getId(), hostId, mspAnswer.getPoolInfo().getLocalPath() + .replaceAll("//", "/")); storagePoolHostDao.persist(poolHost); } else { poolHost.setLocalPath(mspAnswer.getPoolInfo().getLocalPath().replaceAll("//", "/")); } - + StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId); poolVO.setAvailableBytes(mspAnswer.getPoolInfo().getAvailableBytes()); poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes()); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java deleted file mode 100644 index 99b34cbcf18..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategy.java +++ /dev/null @@ -1,28 +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; - -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.datastore.PrimaryDataStore; -import org.apache.cloudstack.storage.volume.VolumeServiceImpl.CreateBaseImageResult; - -public interface TemplateInstallStrategy { - public Void installAsync(TemplateInfo template, PrimaryDataStore store, AsyncCompletionCallback callback); -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java deleted file mode 100644 index 42d49df6c13..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/TemplateInstallStrategyImpl.java +++ /dev/null @@ -1,289 +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; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; -import org.apache.cloudstack.storage.datastore.PrimaryDataStore; -import org.apache.cloudstack.storage.volume.VolumeServiceImpl.CreateBaseImageResult; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -@Component -public class TemplateInstallStrategyImpl implements TemplateInstallStrategy { - private static final Logger s_logger = Logger - .getLogger(TemplateInstallStrategyImpl.class); - @Inject - ObjectInDataStoreManager objectInDataStoreMgr; - @Inject - DataMotionService motionSrv; - @Inject - TemplateDataFactory imageFactory; - protected long waitingTime = 1800; // half an hour - protected long waitingRetries = 10; -/* - protected TemplateInfo waitingForTemplateDownload(TemplateInfo template, - PrimaryDataStore dataStore) { - long retries = this.waitingRetries; - ObjectInDataStoreVO obj = null; - do { - try { - Thread.sleep(waitingTime); - } catch (InterruptedException e) { - s_logger.debug("sleep interrupted", e); - throw new CloudRuntimeException("sleep interrupted", e); - } - - obj = objectInDataStoreMgr.findObject(template.getId(), - template.getType(), dataStore.getId(), dataStore.getRole()); - if (obj == null) { - s_logger.debug("can't find object in db, maybe it's cleaned up already, exit waiting"); - break; - } - if (obj.getState() == ObjectInDataStoreStateMachine.State.Ready) { - break; - } - retries--; - } while (retries > 0); - - if (obj == null || retries <= 0) { - s_logger.debug("waiting too long for template downloading, marked it as failed"); - throw new CloudRuntimeException( - "waiting too long for template downloading, marked it as failed"); - } - return imageFactory.getTemplate(template.getId(), dataStore); - } - - class InstallContext extends AsyncRpcConext { - final TemplateInfo destTemplate; - final TemplateInfo srcTemplate; - - public InstallContext(AsyncCompletionCallback callback, - TemplateInfo destTemplate, TemplateInfo srcTemplate) { - super(callback); - this.destTemplate = destTemplate; - this.srcTemplate = srcTemplate; - } - - } - - @Override - public Void installAsync(TemplateInfo template, PrimaryDataStore store, - AsyncCompletionCallback callback) { - ObjectInDataStoreVO obj = objectInDataStoreMgr.findObject( - template.getId(), template.getType(), store.getId(), - store.getRole()); - TemplateInfo templateOnPrimaryStoreObj = null; - boolean freshNewTemplate = false; - if (obj == null) { - try { - templateOnPrimaryStoreObj = objectInDataStoreMgr.create( - template, store); - freshNewTemplate = true; - } catch (Throwable e) { - obj = objectInDataStoreMgr.findObject(template.getId(), - template.getType(), store.getId(), store.getRole()); - if (obj == null) { - CreateBaseImageResult result = new CreateBaseImageResult( - null); - result.setSuccess(false); - result.setResult(e.toString()); - callback.complete(result); - return null; - } - } - } - - if (!freshNewTemplate - && obj.getState() != ObjectInDataStoreStateMachine.State.Ready) { - try { - templateOnPrimaryStoreObj = waitingForTemplateDownload( - template, store); - } catch (Exception e) { - CreateBaseImageResult result = new CreateBaseImageResult(null); - result.setSuccess(false); - result.setResult(e.toString()); - callback.complete(result); - return null; - } - - CreateBaseImageResult result = new CreateBaseImageResult( - templateOnPrimaryStoreObj); - callback.complete(result); - return null; - } - - try { - objectInDataStoreMgr.update(templateOnPrimaryStoreObj, - ObjectInDataStoreStateMachine.Event.CreateRequested); - } catch (NoTransitionException e) { - try { - objectInDataStoreMgr.update(templateOnPrimaryStoreObj, - ObjectInDataStoreStateMachine.Event.OperationFailed); - } catch (NoTransitionException e1) { - s_logger.debug("state transation failed", e1); - } - CreateBaseImageResult result = new CreateBaseImageResult(null); - result.setSuccess(false); - result.setResult(e.toString()); - callback.complete(result); - return null; - } - - InstallContext context = new InstallContext( - callback, templateOnPrimaryStoreObj, template); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback( - caller.getTarget().installTemplateCallback(null, null)) - .setContext(context); - - store.getDriver().createAsync(templateOnPrimaryStoreObj, caller); - return null; - } - - class CopyTemplateContext extends AsyncRpcConext { - TemplateInfo template; - - public CopyTemplateContext(AsyncCompletionCallback callback, - TemplateInfo template) { - super(callback); - this.template = template; - } - } - - protected Void installTemplateCallback( - AsyncCallbackDispatcher callback, - InstallContext context) { - CreateCmdResult result = callback.getResult(); - TemplateInfo templateOnPrimaryStoreObj = context.destTemplate; - CreateBaseImageResult upResult = new CreateBaseImageResult( - templateOnPrimaryStoreObj); - if (result.isFailed()) { - upResult.setResult(result.getResult()); - context.getParentCallback().complete(upResult); - return null; - } - - ObjectInDataStoreVO obj = objectInDataStoreMgr.findObject( - templateOnPrimaryStoreObj.getId(), templateOnPrimaryStoreObj - .getType(), templateOnPrimaryStoreObj.getDataStore() - .getId(), templateOnPrimaryStoreObj.getDataStore() - .getRole()); - - obj.setInstallPath(result.getPath()); - obj.setSize(result.getSize()); - try { - objectInDataStoreMgr.update(obj, - ObjectInDataStoreStateMachine.Event.OperationSuccessed); - } catch (NoTransitionException e) { - try { - objectInDataStoreMgr.update(obj, - ObjectInDataStoreStateMachine.Event.OperationFailed); - } catch (NoTransitionException e1) { - s_logger.debug("failed to change state", e1); - } - - upResult.setResult(e.toString()); - context.getParentCallback().complete(upResult); - return null; - } - - moveTemplate(context.srcTemplate, templateOnPrimaryStoreObj, obj, - context.getParentCallback()); - return null; - } - - protected void moveTemplate(TemplateInfo srcTemplate, - TemplateInfo destTemplate, ObjectInDataStoreVO obj, - AsyncCompletionCallback callback) { - // move template into primary storage - try { - objectInDataStoreMgr.update(destTemplate, - ObjectInDataStoreStateMachine.Event.CopyingRequested); - } catch (NoTransitionException e) { - s_logger.debug("failed to change state", e); - try { - objectInDataStoreMgr.update(destTemplate, - ObjectInDataStoreStateMachine.Event.OperationFailed); - } catch (NoTransitionException e1) { - - } - CreateBaseImageResult res = new CreateBaseImageResult(destTemplate); - res.setResult("Failed to change state: " + e.toString()); - callback.complete(res); - } - - CopyTemplateContext anotherCall = new CopyTemplateContext( - callback, destTemplate); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setCallback(caller.getTarget().copyTemplateCallback(null, null)) - .setContext(anotherCall); - - motionSrv.copyAsync(srcTemplate, destTemplate, caller); - } - - protected Void copyTemplateCallback( - AsyncCallbackDispatcher callback, - CopyTemplateContext context) { - CopyCommandResult result = callback.getResult(); - TemplateInfo templateOnPrimaryStoreObj = context.template; - if (result.isFailed()) { - CreateBaseImageResult res = new CreateBaseImageResult( - templateOnPrimaryStoreObj); - res.setResult(result.getResult()); - context.getParentCallback().complete(res); - } - DataObjectInStore obj = objectInDataStoreMgr.findObject( - templateOnPrimaryStoreObj, templateOnPrimaryStoreObj.getDataStore()); - - - CreateBaseImageResult res = new CreateBaseImageResult( - templateOnPrimaryStoreObj); - try { - objectInDataStoreMgr.update(obj, - ObjectInDataStoreStateMachine.Event.OperationSuccessed); - } catch (NoTransitionException e) { - s_logger.debug("Failed to update copying state: ", e); - try { - objectInDataStoreMgr.update(templateOnPrimaryStoreObj, - ObjectInDataStoreStateMachine.Event.OperationFailed); - } catch (NoTransitionException e1) { - } - - res.setResult("Failed to update copying state: " + e.toString()); - context.getParentCallback().complete(res); - } - context.getParentCallback().complete(res); - return null; - }*/ - @Override - public Void installAsync(TemplateInfo template, PrimaryDataStore store, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java index e7a42dea750..8d0a5a82bb1 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeDataFactoryImpl.java @@ -41,6 +41,7 @@ public class VolumeDataFactoryImpl implements VolumeDataFactory { VolumeDataStoreDao volumeStoreDao; @Inject DataStoreManager storeMgr; + @Override public VolumeInfo getVolume(long volumeId, DataStore store) { VolumeVO volumeVO = volumeDao.findById(volumeId); @@ -57,7 +58,7 @@ public class VolumeDataFactoryImpl implements VolumeDataFactory { if (volumeVO.getPoolId() == null) { DataStore store = null; VolumeDataStoreVO volumeStore = volumeStoreDao.findByVolume(volumeId); - if ( volumeStore != null ){ + if (volumeStore != null) { store = this.storeMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); } vol = VolumeObject.getVolumeObject(store, volumeVO); @@ -70,8 +71,8 @@ public class VolumeDataFactoryImpl implements VolumeDataFactory { @Override public VolumeInfo getVolume(DataObject volume, DataStore store) { - VolumeInfo vol = (VolumeObject)getVolume(volume.getId(), store); - vol.addPayload(((VolumeInfo)volume).getpayload()); + VolumeInfo vol = getVolume(volume.getId(), store); + vol.addPayload(((VolumeInfo) volume).getpayload()); return vol; } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java index d3e8c543b54..454a50c38bf 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java @@ -38,11 +38,11 @@ public class VolumeEntityImpl implements VolumeEntity { private VolumeInfo volumeInfo; private final VolumeService vs; private VolumeApiResult result; - + public VolumeEntityImpl() { this.vs = null; } - + public VolumeEntityImpl(VolumeInfo volumeObject, VolumeService vs) { this.volumeInfo = volumeObject; this.vs = vs; @@ -52,7 +52,7 @@ public class VolumeEntityImpl implements VolumeEntity { return volumeInfo; } - @Override + @Override public String getUuid() { return volumeInfo.getUuid(); } @@ -92,7 +92,6 @@ public class VolumeEntityImpl implements VolumeEntity { return null; } - @Override public List getApplicableActions() { // TODO Auto-generated method stub @@ -141,7 +140,6 @@ public class VolumeEntityImpl implements VolumeEntity { } - @Override public long getSize() { return volumeInfo.getSize(); @@ -149,7 +147,7 @@ public class VolumeEntityImpl implements VolumeEntity { @Override public DiskFormat getDiskType() { - return null; + return null; } @Override @@ -164,41 +162,40 @@ public class VolumeEntityImpl implements VolumeEntity { @Override public void destroy() { - /*AsyncCallFuture future = vs.deleteVolumeAsync(volumeInfo); - try { - result = future.get(); - if (!result.isSuccess()) { - throw new CloudRuntimeException("Failed to create volume:" + result.getResult()); - } - } catch (InterruptedException e) { - throw new CloudRuntimeException("wait to delete volume info failed", e); - } catch (ExecutionException e) { - throw new CloudRuntimeException("wait to delete volume failed", e); - }*/ + /* + * AsyncCallFuture future = + * vs.deleteVolumeAsync(volumeInfo); try { result = future.get(); if + * (!result.isSuccess()) { throw new + * CloudRuntimeException("Failed to create volume:" + + * result.getResult()); } } catch (InterruptedException e) { throw new + * CloudRuntimeException("wait to delete volume info failed", e); } + * catch (ExecutionException e) { throw new + * CloudRuntimeException("wait to delete volume failed", e); } + */ } - @Override - public Map getDetails() { - // TODO Auto-generated method stub - return null; - } + @Override + public Map getDetails() { + // TODO Auto-generated method stub + return null; + } - @Override - public void addDetail(String name, String value) { - // TODO Auto-generated method stub - - } + @Override + public void addDetail(String name, String value) { + // TODO Auto-generated method stub - @Override - public void delDetail(String name, String value) { - // TODO Auto-generated method stub - - } + } - @Override - public void updateDetail(String name, String value) { - // TODO Auto-generated method stub - - } + @Override + public void delDetail(String name, String value) { + // TODO Auto-generated method stub + + } + + @Override + public void updateDetail(String name, String value) { + // TODO Auto-generated method stub + + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.java deleted file mode 100644 index 9349e6b11cc..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeMotionService.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.volume; - -public interface VolumeMotionService { - boolean copyVolume(String volumeUri, String destVolumeUri); -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 77a0762f0b9..bc14b6ac673 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -104,7 +104,7 @@ public class VolumeObject implements VolumeInfo { } public void setSize(Long size) { - volumeVO.setSize(size); + volumeVO.setSize(size); } @Override @@ -122,10 +122,10 @@ public class VolumeObject implements VolumeInfo { return volumeVO.getSize(); } - public long getVolumeId() { return volumeVO.getId(); } + public boolean stateTransit(Volume.Event event) { boolean result = false; try { @@ -160,16 +160,15 @@ public class VolumeObject implements VolumeInfo { if (this.dataStore == null) { throw new CloudRuntimeException("datastore must be set before using this object"); } - DataObjectInStore obj = objectInStoreMgr.findObject(this.volumeVO.getId(), DataObjectType.VOLUME, this.dataStore.getId(), this.dataStore.getRole()); + DataObjectInStore obj = objectInStoreMgr.findObject(this.volumeVO.getId(), DataObjectType.VOLUME, + this.dataStore.getId(), this.dataStore.getRole()); if (obj.getState() != ObjectInDataStoreStateMachine.State.Ready) { - return this.dataStore.getUri() + - "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + - "&" + EncodingType.SIZE + "=" + this.volumeVO.getSize() + - "&" + EncodingType.NAME + "=" + this.volumeVO.getName(); + return this.dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + + EncodingType.SIZE + "=" + this.volumeVO.getSize() + "&" + EncodingType.NAME + "=" + + this.volumeVO.getName(); } else { - return this.dataStore.getUri() + - "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + - "&" + EncodingType.PATH + "=" + obj.getInstallPath(); + return this.dataStore.getUri() + "&" + EncodingType.OBJTYPE + "=" + DataObjectType.VOLUME + "&" + + EncodingType.PATH + "=" + obj.getInstallPath(); } } @@ -178,32 +177,32 @@ public class VolumeObject implements VolumeInfo { return DataObjectType.VOLUME; } - @Override - public void processEvent( - ObjectInDataStoreStateMachine.Event event) { + public void processEvent(ObjectInDataStoreStateMachine.Event event) { if (this.dataStore == null) { return; } try { Volume.Event volEvent = null; - if ( this.dataStore.getRole() == DataStoreRole.ImageCache){ + if (this.dataStore.getRole() == DataStoreRole.ImageCache) { objectInStoreMgr.update(this, event); return; } if (this.dataStore.getRole() == DataStoreRole.Image) { objectInStoreMgr.update(this, event); - if (this.volumeVO.getState() == Volume.State.Migrating || this.volumeVO.getState() == Volume.State.Copying || this.volumeVO.getState() == Volume.State.Uploaded) { - return; + if (this.volumeVO.getState() == Volume.State.Migrating + || this.volumeVO.getState() == Volume.State.Copying + || this.volumeVO.getState() == Volume.State.Uploaded) { + return; } if (event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { volEvent = Volume.Event.UploadRequested; } else if (event == ObjectInDataStoreStateMachine.Event.MigrationRequested) { - volEvent = Volume.Event.CopyRequested; + volEvent = Volume.Event.CopyRequested; } } else { - if (event == ObjectInDataStoreStateMachine.Event.CreateRequested || - event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { + if (event == ObjectInDataStoreStateMachine.Event.CreateRequested + || event == ObjectInDataStoreStateMachine.Event.CreateOnlyRequested) { volEvent = Volume.Event.CreateRequested; } else if (event == ObjectInDataStoreStateMachine.Event.CopyingRequested) { volEvent = Volume.Event.CopyRequested; @@ -221,16 +220,16 @@ public class VolumeObject implements VolumeInfo { } else if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { volEvent = Volume.Event.OperationFailed; } else if (event == ObjectInDataStoreStateMachine.Event.ResizeRequested) { - volEvent = Volume.Event.ResizeRequested; + volEvent = Volume.Event.ResizeRequested; } this.stateTransit(volEvent); } catch (Exception e) { s_logger.debug("Failed to update state", e); throw new CloudRuntimeException("Failed to update state:" + e.toString()); - } finally{ + } finally { // in case of OperationFailed, expunge the entry - if ( event == ObjectInDataStoreStateMachine.Event.OperationFailed && (this.volumeVO.getState() != Volume.State.Copying - && this.volumeVO.getState() != Volume.State.Uploaded)){ + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed + && (this.volumeVO.getState() != Volume.State.Copying && this.volumeVO.getState() != Volume.State.Uploaded)) { objectInStoreMgr.delete(this); } } @@ -359,22 +358,22 @@ public class VolumeObject implements VolumeInfo { @Override public Object getpayload() { - return this.payload; + return this.payload; } - public VolumeVO getVolume(){ + public VolumeVO getVolume() { return this.volumeVO; } - @Override - public HypervisorType getHypervisorType() { - return this.volumeDao.getHypervisorType(this.volumeVO.getId()); - } + @Override + public HypervisorType getHypervisorType() { + return this.volumeDao.getHypervisorType(this.volumeVO.getId()); + } - @Override - public Long getLastPoolId() { - return this.volumeVO.getLastPoolId(); - } + @Override + public Long getLastPoolId() { + return this.volumeVO.getLastPoolId(); + } @Override public DataTO getTO() { @@ -410,13 +409,15 @@ public class VolumeObject implements VolumeInfo { // image store or imageCache store if (answer instanceof DownloadAnswer) { DownloadAnswer dwdAnswer = (DownloadAnswer) answer; - VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); + VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), + this.getId()); volStore.setInstallPath(dwdAnswer.getInstallPath()); volStore.setChecksum(dwdAnswer.getCheckSum()); this.volumeStoreDao.update(volStore.getId(), volStore); - } else if (answer instanceof CopyCmdAnswer ){ + } else if (answer instanceof CopyCmdAnswer) { CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer; - VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); + VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), + this.getId()); VolumeObjectTO newVol = (VolumeObjectTO) cpyAnswer.getNewData(); volStore.setInstallPath(newVol.getPath()); volStore.setSize(newVol.getSize()); @@ -433,8 +434,8 @@ public class VolumeObject implements VolumeInfo { } - @Override - public ImageFormat getFormat() { - return this.volumeVO.getFormat(); - } + @Override + public ImageFormat getFormat() { + return this.volumeVO.getFormat(); + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 53a4620c368..09752eca00a 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -25,9 +25,6 @@ import java.util.Map; import javax.inject.Inject; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -53,6 +50,8 @@ import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -69,7 +68,6 @@ import com.cloud.host.Host; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; -import com.cloud.storage.Volume.Type; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; @@ -78,9 +76,7 @@ import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.NumbersUtil; -import com.cloud.utils.UriUtils; import com.cloud.utils.db.DB; -import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; @Component @@ -97,10 +93,9 @@ public class VolumeServiceImpl implements VolumeService { @Inject DataMotionService motionSrv; @Inject - TemplateInstallStrategy templateInstallStrategy; - @Inject VolumeDataFactory volFactory; - @Inject SnapshotManager snapshotMgr; + @Inject + SnapshotManager snapshotMgr; @Inject ResourceLimitService _resourceLimitMgr; @Inject @@ -109,7 +104,8 @@ public class VolumeServiceImpl implements VolumeService { AccountManager _accountMgr; @Inject AlertManager _alertMgr; - @Inject VMInstanceDao vmDao; + @Inject + VMInstanceDao vmDao; @Inject ConfigurationDao configDao; @Inject @@ -128,10 +124,12 @@ public class VolumeServiceImpl implements VolumeService { private final DataObject volume; private final AsyncCallFuture future; + /** * @param callback */ - public CreateVolumeContext(AsyncCompletionCallback callback, DataObject volume, AsyncCallFuture future) { + public CreateVolumeContext(AsyncCompletionCallback callback, DataObject volume, + AsyncCallFuture future) { super(callback); this.volume = volume; this.future = future; @@ -153,16 +151,17 @@ public class VolumeServiceImpl implements VolumeService { DataObject volumeOnStore = dataStore.create(volume); volumeOnStore.processEvent(Event.CreateOnlyRequested); - CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, future); + CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, + future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().createVolumeCallback(null, null)) - .setContext(context); + caller.setCallback(caller.getTarget().createVolumeCallback(null, null)).setContext(context); dataStore.getDriver().createAsync(volumeOnStore, caller); return future; } - protected Void createVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + protected Void createVolumeCallback(AsyncCallbackDispatcher callback, + CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); DataObject vo = context.getVolume(); String errMsg = null; @@ -172,7 +171,7 @@ public class VolumeServiceImpl implements VolumeService { vo.processEvent(Event.OperationFailed); errMsg = result.getResult(); } - VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo); + VolumeApiResult volResult = new VolumeApiResult((VolumeObject) vo); if (errMsg != null) { volResult.setResult(errMsg); } @@ -183,10 +182,12 @@ public class VolumeServiceImpl implements VolumeService { private class DeleteVolumeContext extends AsyncRpcConext { private final VolumeObject volume; private final AsyncCallFuture future; + /** * @param callback */ - public DeleteVolumeContext(AsyncCompletionCallback callback, VolumeObject volume, AsyncCallFuture future) { + public DeleteVolumeContext(AsyncCompletionCallback callback, VolumeObject volume, + AsyncCallFuture future) { super(callback); this.volume = volume; this.future = future; @@ -203,7 +204,7 @@ public class VolumeServiceImpl implements VolumeService { @DB @Override - public AsyncCallFuture expungeVolumeAsync(VolumeInfo volume) { + public AsyncCallFuture expungeVolumeAsync(VolumeInfo volume) { AsyncCallFuture future = new AsyncCallFuture(); VolumeApiResult result = new VolumeApiResult(volume); if (volume.getDataStore() == null) { @@ -212,42 +213,32 @@ public class VolumeServiceImpl implements VolumeService { return future; } - String vmName = null; VolumeVO vol = volDao.findById(volume.getId()); - if (vol.getVolumeType() == Type.ROOT && vol.getInstanceId() != null) { - VirtualMachine vm = vmDao.findByIdIncludingRemoved(vol - .getInstanceId()); - if (vm != null) { - vmName = vm.getInstanceName(); - } - } String volumePath = vol.getPath(); Long poolId = vol.getPoolId(); if (poolId == null || volumePath == null || volumePath.trim().isEmpty()) { if (s_logger.isDebugEnabled()) { - s_logger.debug("Marking volume that was never created as destroyed: " - + vol); + s_logger.debug("Marking volume that was never created as destroyed: " + vol); } volDao.remove(vol.getId()); future.complete(result); return future; } - VolumeObject vo = (VolumeObject)volume; + VolumeObject vo = (VolumeObject) volume; volume.processEvent(Event.ExpungeRequested); - DeleteVolumeContext context = new DeleteVolumeContext(null, vo, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)) - .setContext(context); + caller.setCallback(caller.getTarget().deleteVolumeCallback(null, null)).setContext(context); volume.getDataStore().getDriver().deleteAsync(volume, caller); return future; } - public Void deleteVolumeCallback(AsyncCallbackDispatcher callback, DeleteVolumeContext context) { + public Void deleteVolumeCallback(AsyncCallbackDispatcher callback, + DeleteVolumeContext context) { CommandResult result = callback.getResult(); VolumeObject vo = context.getVolume(); VolumeApiResult apiResult = new VolumeApiResult(vo); @@ -289,9 +280,10 @@ public class VolumeServiceImpl implements VolumeService { private final TemplateInfo srcTemplate; private final AsyncCallFuture future; final DataObject destObj; - public CreateBaseImageContext(AsyncCompletionCallback callback, VolumeInfo volume, PrimaryDataStore datastore, - TemplateInfo srcTemplate, - AsyncCallFuture future, DataObject destObj) { + + public CreateBaseImageContext(AsyncCompletionCallback callback, VolumeInfo volume, + PrimaryDataStore datastore, TemplateInfo srcTemplate, AsyncCallFuture future, + DataObject destObj) { super(callback); this.volume = volume; this.dataStore = datastore; @@ -320,6 +312,7 @@ public class VolumeServiceImpl implements VolumeService { static class CreateBaseImageResult extends CommandResult { final TemplateInfo template; + public CreateBaseImageResult(TemplateInfo template) { super(); this.template = template; @@ -327,61 +320,60 @@ public class VolumeServiceImpl implements VolumeService { } private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) { - int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); - int sleepTime = 120; - int tries = storagePoolMaxWaitSeconds/sleepTime; - while (tries > 0) { - TemplateInfo tmpl = store.getTemplate(template.getId()); - if (tmpl != null) { - return tmpl; - } - try { - Thread.sleep(sleepTime * 1000); - } catch (InterruptedException e) { - s_logger.debug("waiting for template download been interrupted: " + e.toString()); - } - tries--; - } - return null; + int storagePoolMaxWaitSeconds = NumbersUtil.parseInt( + configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); + int sleepTime = 120; + int tries = storagePoolMaxWaitSeconds / sleepTime; + while (tries > 0) { + TemplateInfo tmpl = store.getTemplate(template.getId()); + if (tmpl != null) { + return tmpl; + } + try { + Thread.sleep(sleepTime * 1000); + } catch (InterruptedException e) { + s_logger.debug("waiting for template download been interrupted: " + e.toString()); + } + tries--; + } + return null; } + @DB - protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, AsyncCallFuture future) { + protected void createBaseImageAsync(VolumeInfo volume, PrimaryDataStore dataStore, TemplateInfo template, + AsyncCallFuture future) { DataObject templateOnPrimaryStoreObj = dataStore.create(template); CreateBaseImageContext context = new CreateBaseImageContext(null, volume, - dataStore, - template, - future, templateOnPrimaryStoreObj); + dataStore, template, future, templateOnPrimaryStoreObj); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)) - .setContext(context); + caller.setCallback(caller.getTarget().copyBaseImageCallback(null, null)).setContext(context); try { - templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); + templateOnPrimaryStoreObj.processEvent(Event.CreateOnlyRequested); } catch (Exception e) { s_logger.info("Got exception in case of multi-thread"); - try { - templateOnPrimaryStoreObj = waitForTemplateDownloaded(dataStore, template); - } catch(Exception e1) { - s_logger.debug("wait for template:" + template.getId() + " downloading finished, but failed"); - VolumeApiResult result = new VolumeApiResult(volume); - result.setResult(e1.toString()); - future.complete(result); - return; - } - if (templateOnPrimaryStoreObj == null) { - VolumeApiResult result = new VolumeApiResult(volume); + try { + templateOnPrimaryStoreObj = waitForTemplateDownloaded(dataStore, template); + } catch (Exception e1) { + s_logger.debug("wait for template:" + template.getId() + " downloading finished, but failed"); + VolumeApiResult result = new VolumeApiResult(volume); + result.setResult(e1.toString()); + future.complete(result); + return; + } + if (templateOnPrimaryStoreObj == null) { + VolumeApiResult result = new VolumeApiResult(volume); result.setResult("wait for template:" + template.getId() + " downloading finished, but failed"); future.complete(result); return; - } else { - s_logger.debug("waiting for template:" + template.getId() + " downloading finished, success"); - createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future); - return; - } + } else { + s_logger.debug("waiting for template:" + template.getId() + " downloading finished, success"); + createVolumeFromBaseImageAsync(volume, templateOnPrimaryStoreObj, dataStore, future); + return; + } } - try { motionSrv.copyAsync(template, templateOnPrimaryStoreObj, caller); } catch (Exception e) { @@ -395,7 +387,8 @@ public class VolumeServiceImpl implements VolumeService { } @DB - protected Void copyBaseImageCallback(AsyncCallbackDispatcher callback, CreateBaseImageContext context) { + protected Void copyBaseImageCallback(AsyncCallbackDispatcher callback, + CreateBaseImageContext context) { CopyCommandResult result = callback.getResult(); VolumeApiResult res = new VolumeApiResult(context.getVolume()); @@ -416,34 +409,33 @@ public class VolumeServiceImpl implements VolumeService { private class CreateVolumeFromBaseImageContext extends AsyncRpcConext { private final DataObject vo; private final AsyncCallFuture future; - private final DataStore primaryStore; private final DataObject templateOnStore; private final SnapshotInfo snapshot; + public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, DataObject vo, - DataStore primaryStore, - DataObject templateOnStore, - AsyncCallFuture future, SnapshotInfo snapshot) { + DataStore primaryStore, DataObject templateOnStore, AsyncCallFuture future, + SnapshotInfo snapshot) { super(callback); this.vo = vo; this.future = future; - this.primaryStore = primaryStore; this.templateOnStore = templateOnStore; this.snapshot = snapshot; } - public AsyncCallFuture getFuture() { return this.future; } } @DB - protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, PrimaryDataStore pd, AsyncCallFuture future) { + protected void createVolumeFromBaseImageAsync(VolumeInfo volume, DataObject templateOnPrimaryStore, + PrimaryDataStore pd, AsyncCallFuture future) { DataObject volumeOnPrimaryStorage = pd.create(volume); volumeOnPrimaryStorage.processEvent(Event.CreateOnlyRequested); - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext( + null, volumeOnPrimaryStorage, pd, templateOnPrimaryStore, future, null); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().createVolumeFromBaseImageCallBack(null, null)); caller.setContext(context); @@ -452,10 +444,12 @@ public class VolumeServiceImpl implements VolumeService { } @DB - protected Void createVolumeFromBaseImageCallBack(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { + protected Void createVolumeFromBaseImageCallBack( + AsyncCallbackDispatcher callback, + CreateVolumeFromBaseImageContext context) { DataObject vo = context.vo; CopyCommandResult result = callback.getResult(); - VolumeApiResult volResult = new VolumeApiResult((VolumeObject)vo); + VolumeApiResult volResult = new VolumeApiResult((VolumeObject) vo); if (result.isSuccess()) { vo.processEvent(Event.OperationSuccessed, result.getAnswer()); @@ -471,11 +465,11 @@ public class VolumeServiceImpl implements VolumeService { @DB @Override - public AsyncCallFuture createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, TemplateInfo template) { + public AsyncCallFuture createVolumeFromTemplateAsync(VolumeInfo volume, long dataStoreId, + TemplateInfo template) { PrimaryDataStore pd = dataStoreMgr.getPrimaryDataStore(dataStoreId); TemplateInfo templateOnPrimaryStore = pd.getTemplate(template.getId()); AsyncCallFuture future = new AsyncCallFuture(); - VolumeApiResult result = new VolumeApiResult(volume); if (templateOnPrimaryStore == null) { createBaseImageAsync(volume, pd, template, future); @@ -488,8 +482,7 @@ public class VolumeServiceImpl implements VolumeService { @Override @DB - public boolean destroyVolume(long volumeId) - throws ConcurrentOperationException { + public boolean destroyVolume(long volumeId) throws ConcurrentOperationException { VolumeInfo vol = volFactory.getVolume(volumeId); vol.processEvent(Event.DestroyRequested); @@ -501,59 +494,59 @@ public class VolumeServiceImpl implements VolumeService { } @Override - public AsyncCallFuture createVolumeFromSnapshot( - VolumeInfo volume, DataStore store, SnapshotInfo snapshot) { + public AsyncCallFuture createVolumeFromSnapshot(VolumeInfo volume, DataStore store, + SnapshotInfo snapshot) { AsyncCallFuture future = new AsyncCallFuture(); try { - DataObject volumeOnStore = store.create(volume); - volumeOnStore.processEvent(Event.CreateOnlyRequested); - snapshot.processEvent(Event.CopyingRequested); - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(null, - volume, store, volumeOnStore, future, snapshot); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)) - .setContext(context); - motionSrv.copyAsync(snapshot, volumeOnStore, caller); + DataObject volumeOnStore = store.create(volume); + volumeOnStore.processEvent(Event.CreateOnlyRequested); + snapshot.processEvent(Event.CopyingRequested); + CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext( + null, volume, store, volumeOnStore, future, snapshot); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().createVolumeFromSnapshotCallback(null, null)).setContext(context); + motionSrv.copyAsync(snapshot, volumeOnStore, caller); } catch (Exception e) { - s_logger.debug("create volume from snapshot failed", e); - VolumeApiResult result = new VolumeApiResult(volume); - result.setResult(e.toString()); - future.complete(result); + s_logger.debug("create volume from snapshot failed", e); + VolumeApiResult result = new VolumeApiResult(volume); + result.setResult(e.toString()); + future.complete(result); } return future; } - protected Void createVolumeFromSnapshotCallback(AsyncCallbackDispatcher callback, - CreateVolumeFromBaseImageContext context) { - CopyCommandResult result = callback.getResult(); - VolumeInfo volume = (VolumeInfo)context.templateOnStore; - SnapshotInfo snapshot = context.snapshot; - VolumeApiResult apiResult = new VolumeApiResult(volume); - Event event = null; - if (result.isFailed()) { - apiResult.setResult(result.getResult()); - event = Event.OperationFailed; - } else { - event = Event.OperationSuccessed; - } + protected Void createVolumeFromSnapshotCallback( + AsyncCallbackDispatcher callback, + CreateVolumeFromBaseImageContext context) { + CopyCommandResult result = callback.getResult(); + VolumeInfo volume = (VolumeInfo) context.templateOnStore; + SnapshotInfo snapshot = context.snapshot; + VolumeApiResult apiResult = new VolumeApiResult(volume); + Event event = null; + if (result.isFailed()) { + apiResult.setResult(result.getResult()); + event = Event.OperationFailed; + } else { + event = Event.OperationSuccessed; + } - try { - if (result.isSuccess()) { - volume.processEvent(event, result.getAnswer()); - } else { - volume.processEvent(event); - } - snapshot.processEvent(event); - } catch (Exception e) { - s_logger.debug("create volume from snapshot failed", e); - apiResult.setResult(e.toString()); - } + try { + if (result.isSuccess()) { + volume.processEvent(event, result.getAnswer()); + } else { + volume.processEvent(event); + } + snapshot.processEvent(event); + } catch (Exception e) { + s_logger.debug("create volume from snapshot failed", e); + apiResult.setResult(e.toString()); + } - AsyncCallFuture future = context.future; - future.complete(apiResult); - return null; + AsyncCallFuture future = context.future; + future.complete(apiResult); + return null; } protected VolumeVO duplicateVolumeOnAnotherStorage(Volume volume, StoragePool pool) { @@ -568,113 +561,107 @@ public class VolumeServiceImpl implements VolumeService { return volDao.persist(newVol); } - private class CopyVolumeContext extends AsyncRpcConext { final VolumeInfo srcVolume; final VolumeInfo destVolume; - final DataStore destStore; final AsyncCallFuture future; + /** * @param callback */ - public CopyVolumeContext(AsyncCompletionCallback callback, AsyncCallFuture future, VolumeInfo srcVolume, VolumeInfo destVolume, - DataStore destStore) { + public CopyVolumeContext(AsyncCompletionCallback callback, AsyncCallFuture future, + VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) { super(callback); this.srcVolume = srcVolume; this.destVolume = destVolume; - this.destStore = destStore; this.future = future; } } - + protected AsyncCallFuture copyVolumeFromImageToPrimary(VolumeInfo srcVolume, DataStore destStore) { - AsyncCallFuture future = new AsyncCallFuture(); - VolumeApiResult res = new VolumeApiResult(srcVolume); - VolumeInfo destVolume = null; - try { - destVolume = (VolumeInfo)destStore.create(srcVolume); - destVolume.processEvent(Event.CopyingRequested); - srcVolume.processEvent(Event.CopyingRequested); + AsyncCallFuture future = new AsyncCallFuture(); + VolumeApiResult res = new VolumeApiResult(srcVolume); + VolumeInfo destVolume = null; + try { + destVolume = (VolumeInfo) destStore.create(srcVolume); + destVolume.processEvent(Event.CopyingRequested); + srcVolume.processEvent(Event.CopyingRequested); - CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, - destVolume, - destStore); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyVolumeFromImageToPrimaryCallback(null, null)) - .setContext(context); + CopyVolumeContext context = new CopyVolumeContext(null, future, + srcVolume, destVolume, destStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyVolumeFromImageToPrimaryCallback(null, null)).setContext(context); - motionSrv.copyAsync(srcVolume, destVolume, caller); - return future; - } catch (Exception e) { - s_logger.error("failed to copy volume from image store", e); - if (destVolume != null) { - destVolume.processEvent(Event.OperationFailed); - } - - srcVolume.processEvent(Event.OperationFailed); - res.setResult(e.toString()); - future.complete(res); - return future; - } + motionSrv.copyAsync(srcVolume, destVolume, caller); + return future; + } catch (Exception e) { + s_logger.error("failed to copy volume from image store", e); + if (destVolume != null) { + destVolume.processEvent(Event.OperationFailed); + } + + srcVolume.processEvent(Event.OperationFailed); + res.setResult(e.toString()); + future.complete(res); + return future; + } } - protected Void copyVolumeFromImageToPrimaryCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { - VolumeInfo srcVolume = context.srcVolume; - VolumeInfo destVolume = context.destVolume; - CopyCommandResult result = callback.getResult(); - AsyncCallFuture future = context.future; - VolumeApiResult res = new VolumeApiResult(destVolume); - try { - if (res.isFailed()) { - destVolume.processEvent(Event.OperationFailed); - srcVolume.processEvent(Event.OperationFailed); - res.setResult(result.getResult()); - future.complete(res); - } + protected Void copyVolumeFromImageToPrimaryCallback( + AsyncCallbackDispatcher callback, + CopyVolumeContext context) { + VolumeInfo srcVolume = context.srcVolume; + VolumeInfo destVolume = context.destVolume; + CopyCommandResult result = callback.getResult(); + AsyncCallFuture future = context.future; + VolumeApiResult res = new VolumeApiResult(destVolume); + try { + if (res.isFailed()) { + destVolume.processEvent(Event.OperationFailed); + srcVolume.processEvent(Event.OperationFailed); + res.setResult(result.getResult()); + future.complete(res); + } - srcVolume.processEvent(Event.OperationSuccessed); - destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); - srcVolume.getDataStore().delete(srcVolume); - future.complete(res); - } catch (Exception e) { - res.setResult(e.toString()); - future.complete(res); - } - return null; + srcVolume.processEvent(Event.OperationSuccessed); + destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); + srcVolume.getDataStore().delete(srcVolume); + future.complete(res); + } catch (Exception e) { + res.setResult(e.toString()); + future.complete(res); + } + return null; } - + @Override - public AsyncCallFuture copyVolume(VolumeInfo srcVolume, - DataStore destStore) { - - if (srcVolume.getState() == Volume.State.Uploaded) { - return copyVolumeFromImageToPrimary(srcVolume, destStore); - } - + public AsyncCallFuture copyVolume(VolumeInfo srcVolume, DataStore destStore) { + + if (srcVolume.getState() == Volume.State.Uploaded) { + return copyVolumeFromImageToPrimary(srcVolume, destStore); + } + AsyncCallFuture future = new AsyncCallFuture(); VolumeApiResult res = new VolumeApiResult(srcVolume); try { if (!snapshotMgr.canOperateOnVolume(srcVolume)) { - s_logger.debug( - "There are snapshots creating on this volume, can not move this volume"); + s_logger.debug("There are snapshots creating on this volume, can not move this volume"); res.setResult("There are snapshots creating on this volume, can not move this volume"); future.complete(res); return future; } - VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, (StoragePool)destStore); + VolumeVO destVol = duplicateVolumeOnAnotherStorage(srcVolume, (StoragePool) destStore); VolumeInfo destVolume = volFactory.getVolume(destVol.getId(), destStore); destVolume.processEvent(Event.MigrationRequested); srcVolume.processEvent(Event.MigrationRequested); - CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, - destVolume, - destStore); + CopyVolumeContext context = new CopyVolumeContext(null, future, + srcVolume, destVolume, destStore); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().copyVolumeCallBack(null, null)) - .setContext(context); + caller.setCallback(caller.getTarget().copyVolumeCallBack(null, null)).setContext(context); motionSrv.copyAsync(srcVolume, destVolume, caller); } catch (Exception e) { s_logger.debug("Failed to copy volume" + e); @@ -684,7 +671,8 @@ public class VolumeServiceImpl implements VolumeService { return future; } - protected Void copyVolumeCallBack(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + protected Void copyVolumeCallBack(AsyncCallbackDispatcher callback, + CopyVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); @@ -711,7 +699,7 @@ public class VolumeServiceImpl implements VolumeService { future.complete(res); return null; } catch (Exception e) { - s_logger.debug("Failed to process copy volume callback",e); + s_logger.debug("Failed to process copy volume callback", e); res.setResult(e.toString()); future.complete(res); } @@ -719,12 +707,11 @@ public class VolumeServiceImpl implements VolumeService { return null; } - private class MigrateVolumeContext extends AsyncRpcConext { final VolumeInfo srcVolume; final VolumeInfo destVolume; - final DataStore destStore; final AsyncCallFuture future; + /** * @param callback */ @@ -733,7 +720,6 @@ public class VolumeServiceImpl implements VolumeService { super(callback); this.srcVolume = srcVolume; this.destVolume = destVolume; - this.destStore = destStore; this.future = future; } } @@ -768,7 +754,6 @@ public class VolumeServiceImpl implements VolumeService { protected Void migrateVolumeCallBack(AsyncCallbackDispatcher callback, MigrateVolumeContext context) { VolumeInfo srcVolume = context.srcVolume; - VolumeInfo destVolume = context.destVolume; CopyCommandResult result = callback.getResult(); AsyncCallFuture future = context.future; VolumeApiResult res = new VolumeApiResult(srcVolume); @@ -793,6 +778,7 @@ public class VolumeServiceImpl implements VolumeService { private class MigrateVmWithVolumesContext extends AsyncRpcConext { final Map volumeToPool; final AsyncCallFuture future; + /** * @param callback */ @@ -810,7 +796,8 @@ public class VolumeServiceImpl implements VolumeService { AsyncCallFuture future = new AsyncCallFuture(); CommandResult res = new CommandResult(); try { - // Check to make sure there are no snapshot operations on a volume and + // Check to make sure there are no snapshot operations on a volume + // and // put it in the migrating state. List volumesMigrating = new ArrayList(); for (Map.Entry entry : volumeMap.entrySet()) { @@ -820,7 +807,8 @@ public class VolumeServiceImpl implements VolumeService { res.setResult("Snapshots are being created on a volume. Volumes cannot be migrated now."); future.complete(res); - // All the volumes that are already in migrating state need to be put back in ready state. + // All the volumes that are already in migrating state need + // to be put back in ready state. for (VolumeInfo volumeMigrating : volumesMigrating) { volumeMigrating.processEvent(Event.OperationFailed); } @@ -876,7 +864,6 @@ public class VolumeServiceImpl implements VolumeService { return null; } - @Override public AsyncCallFuture registerVolume(VolumeInfo volume, DataStore store) { @@ -885,7 +872,8 @@ public class VolumeServiceImpl implements VolumeService { volumeOnStore.processEvent(Event.CreateOnlyRequested); - CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, future); + CreateVolumeContext context = new CreateVolumeContext(null, volumeOnStore, + future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().registerVolumeCallback(null, null)); caller.setContext(context); @@ -894,81 +882,81 @@ public class VolumeServiceImpl implements VolumeService { return future; } - protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { + protected Void registerVolumeCallback(AsyncCallbackDispatcher callback, + CreateVolumeContext context) { CreateCmdResult result = callback.getResult(); try { - VolumeObject vo = (VolumeObject)context.volume; - if (result.isFailed()) { - vo.processEvent(Event.OperationFailed); - } else { - vo.processEvent(Event.OperationSuccessed, result.getAnswer()); - } + VolumeObject vo = (VolumeObject) context.volume; + if (result.isFailed()) { + vo.processEvent(Event.OperationFailed); + } else { + vo.processEvent(Event.OperationSuccessed, result.getAnswer()); + } - _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, - vo.getSize()); - VolumeApiResult res = new VolumeApiResult(vo); - context.future.complete(res); - return null; + _resourceLimitMgr.incrementResourceCount(vo.getAccountId(), ResourceType.secondary_storage, vo.getSize()); + VolumeApiResult res = new VolumeApiResult(vo); + context.future.complete(res); + return null; } catch (Exception e) { - s_logger.error("register volume failed: ", e); - VolumeApiResult res = new VolumeApiResult(null); - context.future.complete(res); - return null; + s_logger.error("register volume failed: ", e); + VolumeApiResult res = new VolumeApiResult(null); + context.future.complete(res); + return null; } } - - @Override - public AsyncCallFuture resize(VolumeInfo volume) { - AsyncCallFuture future = new AsyncCallFuture(); - VolumeApiResult result = new VolumeApiResult(volume); - try { - volume.processEvent(Event.ResizeRequested); - } catch (Exception e) { - s_logger.debug("Failed to change state to resize", e); - result.setResult(e.toString()); - future.complete(result); - return future; - } - CreateVolumeContext context = new CreateVolumeContext(null, volume, future); + @Override + public AsyncCallFuture resize(VolumeInfo volume) { + AsyncCallFuture future = new AsyncCallFuture(); + VolumeApiResult result = new VolumeApiResult(volume); + try { + volume.processEvent(Event.ResizeRequested); + } catch (Exception e) { + s_logger.debug("Failed to change state to resize", e); + result.setResult(e.toString()); + future.complete(result); + return future; + } + CreateVolumeContext context = new CreateVolumeContext(null, volume, future); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setCallback(caller.getTarget().resizeVolumeCallback(caller, context)).setContext(context); - volume.getDataStore().getDriver().resize(volume, caller); - return future; - } + volume.getDataStore().getDriver().resize(volume, caller); + return future; + } - protected Void resizeVolumeCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { - CreateCmdResult result = callback.getResult(); - AsyncCallFuture future = context.future; - VolumeInfo volume = (VolumeInfo)context.volume; + protected Void resizeVolumeCallback(AsyncCallbackDispatcher callback, + CreateVolumeContext context) { + CreateCmdResult result = callback.getResult(); + AsyncCallFuture future = context.future; + VolumeInfo volume = (VolumeInfo) context.volume; - if (result.isFailed()) { - try { - volume.processEvent(Event.OperationFailed); - } catch (Exception e) { - s_logger.debug("Failed to change state", e); - } - VolumeApiResult res = new VolumeApiResult(volume); - res.setResult(result.getResult()); - future.complete(res); - return null; - } + if (result.isFailed()) { + try { + volume.processEvent(Event.OperationFailed); + } catch (Exception e) { + s_logger.debug("Failed to change state", e); + } + VolumeApiResult res = new VolumeApiResult(volume); + res.setResult(result.getResult()); + future.complete(res); + return null; + } - try { - volume.processEvent(Event.OperationSuccessed); - } catch(Exception e) { - s_logger.debug("Failed to change state", e); - VolumeApiResult res = new VolumeApiResult(volume); - res.setResult(result.getResult()); - future.complete(res); - return null; - } + try { + volume.processEvent(Event.OperationSuccessed); + } catch (Exception e) { + s_logger.debug("Failed to change state", e); + VolumeApiResult res = new VolumeApiResult(volume); + res.setResult(result.getResult()); + future.complete(res); + return null; + } - VolumeApiResult res = new VolumeApiResult(volume); - future.complete(res); + VolumeApiResult res = new VolumeApiResult(volume); + future.complete(res); - return null; - } + return null; + } @Override public void handleVolumeSync(DataStore store) { @@ -977,8 +965,6 @@ public class VolumeServiceImpl implements VolumeService { return; } long storeId = store.getId(); - Long zoneId = store.getScope().getScopeId(); - Map volumeInfos = listVolume(store); if (volumeInfos == null) { @@ -987,10 +973,10 @@ public class VolumeServiceImpl implements VolumeService { List dbVolumes = _volumeStoreDao.listByStoreId(storeId); List toBeDownloaded = new ArrayList(dbVolumes); - for (VolumeDataStoreVO volumeStore : dbVolumes){ + for (VolumeDataStoreVO volumeStore : dbVolumes) { VolumeVO volume = _volumeDao.findById(volumeStore.getVolumeId()); - //Exists then don't download - if (volumeInfos.containsKey(volume.getId())){ + // Exists then don't download + if (volumeInfos.containsKey(volume.getId())) { TemplateProp volInfo = volumeInfos.remove(volume.getId()); toBeDownloaded.remove(volumeStore); s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table"); @@ -1003,7 +989,8 @@ public class VolumeServiceImpl implements VolumeService { volumeStore.setErrorString(msg); s_logger.info("msg"); if (volumeStore.getDownloadUrl() == null) { - msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + "is corrupted, please check in image store: " + volumeStore.getDataStoreId(); + msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + + "is corrupted, please check in image store: " + volumeStore.getDataStoreId(); s_logger.warn(msg); } else { toBeDownloaded.add(volumeStore); @@ -1026,14 +1013,13 @@ public class VolumeServiceImpl implements VolumeService { if (volInfo.getSize() > 0) { try { - String url = _volumeStoreDao.findByVolume(volume.getId()).getDownloadUrl(); _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), - com.cloud.configuration.Resource.ResourceType.secondary_storage, - volInfo.getSize() - volInfo.getPhysicalSize()); + com.cloud.configuration.Resource.ResourceType.secondary_storage, volInfo.getSize() + - volInfo.getPhysicalSize()); } catch (ResourceAllocationException e) { s_logger.warn(e.getMessage()); - _alertMgr.sendAlert(_alertMgr.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), - volume.getPodId(), e.getMessage(), e.getMessage()); + _alertMgr.sendAlert(AlertManager.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, + volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage()); } finally { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), com.cloud.configuration.Resource.ResourceType.secondary_storage.getOrdinal()); @@ -1044,33 +1030,36 @@ public class VolumeServiceImpl implements VolumeService { } // Volume is not on secondary but we should download. if (volumeStore.getDownloadState() != Status.DOWNLOADED) { - s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly"); + s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + + ", will request download to start/resume shortly"); toBeDownloaded.add(volumeStore); } } - //Download volumes which haven't been downloaded yet. + // Download volumes which haven't been downloaded yet. if (toBeDownloaded.size() > 0) { for (VolumeDataStoreVO volumeHost : toBeDownloaded) { - if (volumeHost.getDownloadUrl() == null) { // If url is null we can't initiate the download + if (volumeHost.getDownloadUrl() == null) { // If url is null we + // can't initiate the + // download continue; } s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName()); - //TODO: pass a callback later + // TODO: pass a callback later VolumeInfo vol = volFactory.getVolume(volumeHost.getVolumeId()); createVolumeAsync(vol, store); } } - //Delete volumes which are not present on DB. + // Delete volumes which are not present on DB. /* - for (Long uniqueName : volumeInfos.keySet()) { - TemplateProp vInfo = volumeInfos.get(uniqueName); - expungeVolumeAsync(volFactory.getVolume(vInfo.getId(), store)); - - String description = "Deleted volume " + vInfo.getTemplateName() + " on image store " + storeId; - s_logger.info(description); - }*/ + * for (Long uniqueName : volumeInfos.keySet()) { TemplateProp vInfo = + * volumeInfos.get(uniqueName); + * expungeVolumeAsync(volFactory.getVolume(vInfo.getId(), store)); + * + * String description = "Deleted volume " + vInfo.getTemplateName() + + * " on image store " + storeId; s_logger.info(description); } + */ } @@ -1079,7 +1068,7 @@ public class VolumeServiceImpl implements VolumeService { EndPoint ep = _epSelector.select(store); Answer answer = ep.sendMessage(cmd); if (answer != null && answer.getResult()) { - ListVolumeAnswer tanswer = (ListVolumeAnswer)answer; + ListVolumeAnswer tanswer = (ListVolumeAnswer) answer; return tanswer.getTemplateInfo(); } else { if (s_logger.isDebugEnabled()) { @@ -1092,23 +1081,23 @@ public class VolumeServiceImpl implements VolumeService { @Override public SnapshotInfo takeSnapshot(VolumeInfo volume) { - VolumeObject vol = (VolumeObject)volume; - vol.stateTransit(Volume.Event.SnapshotRequested); + VolumeObject vol = (VolumeObject) volume; + vol.stateTransit(Volume.Event.SnapshotRequested); - SnapshotInfo snapshot = null; - try { - snapshot = snapshotMgr.takeSnapshot(volume); - } catch (Exception e) { - s_logger.debug("Take snapshot: " + volume.getId() + " failed: " + e.toString()); - } finally { - if (snapshot != null) { - vol.stateTransit(Volume.Event.OperationSucceeded); - } else { - vol.stateTransit(Volume.Event.OperationFailed); - } - } + SnapshotInfo snapshot = null; + try { + snapshot = snapshotMgr.takeSnapshot(volume); + } catch (Exception e) { + s_logger.debug("Take snapshot: " + volume.getId() + " failed: " + e.toString()); + } finally { + if (snapshot != null) { + vol.stateTransit(Volume.Event.OperationSucceeded); + } else { + vol.stateTransit(Volume.Event.OperationFailed); + } + } - return snapshot; + return snapshot; } } diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java index 6ad951a2e05..ddbccb2fdb5 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/ConfiguratorTest.java @@ -18,56 +18,50 @@ */ package org.apache.cloudstack.storage.volume.test; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.util.HashMap; import java.util.List; -import java.util.Map; - import javax.inject.Inject; -import javax.naming.ConfigurationException; - import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import com.cloud.dc.ClusterVO; import com.cloud.dc.dao.ClusterDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:/testContext.xml") +@ContextConfiguration(locations = "classpath:/testContext.xml") public class ConfiguratorTest { - @Inject + @Inject List providers; - + @Inject ClusterDao clusterDao; + @Before public void setup() { - /* ClusterVO cluster = new ClusterVO(); - cluster.setHypervisorType(HypervisorType.XenServer.toString()); - Mockito.when(clusterDao.findById(Mockito.anyLong())).thenReturn(cluster); - try { - providerMgr.configure("manager", null); - } catch (ConfigurationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - }*/ + /* + * ClusterVO cluster = new ClusterVO(); + * cluster.setHypervisorType(HypervisorType.XenServer.toString()); + * Mockito + * .when(clusterDao.findById(Mockito.anyLong())).thenReturn(cluster); + * try { providerMgr.configure("manager", null); } catch + * (ConfigurationException e) { // TODO Auto-generated catch block + * e.printStackTrace(); } + */ } + @Test public void testLoadConfigurator() { - /*for (PrimaryDataStoreConfigurator configurator : configurators) { - System.out.println(configurator.getClass().getName()); - }*/ + /* + * for (PrimaryDataStoreConfigurator configurator : configurators) { + * System.out.println(configurator.getClass().getName()); } + */ } - + @Test public void testProvider() { for (PrimaryDataStoreProvider provider : providers) { @@ -76,19 +70,21 @@ public class ConfiguratorTest { } } } - + @Test public void getProvider() { - // assertNotNull(providerMgr.getDataStoreProvider("sample primary data store provider")); + // assertNotNull(providerMgr.getDataStoreProvider("sample primary data store provider")); } - + @Test public void createDataStore() { - /*PrimaryDataStoreProvider provider = providerMgr.getDataStoreProvider("sample primary data store provider"); - Map params = new HashMap(); - params.put("url", "nfs://localhost/mnt"); - params.put("clusterId", "1"); - params.put("name", "nfsprimary"); - assertNotNull(provider.registerDataStore(params));*/ + /* + * PrimaryDataStoreProvider provider = + * providerMgr.getDataStoreProvider("sample primary data store provider" + * ); Map params = new HashMap(); + * params.put("url", "nfs://localhost/mnt"); params.put("clusterId", + * "1"); params.put("name", "nfsprimary"); + * assertNotNull(provider.registerDataStore(params)); + */ } } diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java index f19d68e8ea1..b7874ebb111 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/Server.java @@ -22,19 +22,22 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; public class Server { Server1 svr; + public Server() { svr = new Server1(); } + void foo() { - // svr.foo1("foo", new AsyncCallbackDispatcher(this).setOperationName("callback").setContextParam("name", "foo")); + // svr.foo1("foo", new + // AsyncCallbackDispatcher(this).setOperationName("callback").setContextParam("name", + // "foo")); } - + void foocallback(AsyncCallbackDispatcher callback) { /* - System.out.println(callback.getContextParam("name")); - String result = callback.getResult(); - System.out.println(result); - */ + * System.out.println(callback.getContextParam("name")); String result = + * callback.getResult(); System.out.println(result); + */ } - + } diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java index 1d3202f123b..eb871a54ae2 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestConfiguration.java @@ -33,7 +33,7 @@ public class TestConfiguration { public ImageMotionService imageMotion() { return Mockito.mock(ImageMotionService.class); } - + @Bean public ClusterDao clusterDao() { return Mockito.mock(ClusterDaoImpl.class); diff --git a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java index 67418717989..df099692db4 100644 --- a/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java +++ b/engine/storage/volume/test/org/apache/cloudstack/storage/volume/test/TestInProcessAsync.java @@ -25,14 +25,15 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:/resource/testContext.xml") +@ContextConfiguration(locations = "classpath:/resource/testContext.xml") public class TestInProcessAsync { Server svr; - @Before + + @Before public void setup() { svr = new Server(); } - + @Test public void testRpc() { svr.foo(); diff --git a/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java b/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java index 5de3f6be796..76ce6631c74 100644 --- a/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java +++ b/plugins/storage-allocators/random/src/org/apache/cloudstack/storage/allocator/RandomStoragePoolAllocator.java @@ -33,44 +33,45 @@ import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; -@Local(value=StoragePoolAllocator.class) +@Local(value = StoragePoolAllocator.class) public class RandomStoragePoolAllocator extends AbstractStoragePoolAllocator { private static final Logger s_logger = Logger.getLogger(RandomStoragePoolAllocator.class); - - @Override - public List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { - List suitablePools = new ArrayList(); - - long dcId = plan.getDataCenterId(); - Long podId = plan.getPodId(); - Long clusterId = plan.getClusterId(); + @Override + public List select(DiskProfile dskCh, VirtualMachineProfile vmProfile, + DeploymentPlan plan, ExcludeList avoid, int returnUpTo) { + + List suitablePools = new ArrayList(); + + long dcId = plan.getDataCenterId(); + Long podId = plan.getPodId(); + Long clusterId = plan.getClusterId(); s_logger.debug("Looking for pools in dc: " + dcId + " pod:" + podId + " cluster:" + clusterId); - List pools = _storagePoolDao.listBy(dcId, podId, clusterId, ScopeType.CLUSTER); + List pools = _storagePoolDao.listBy(dcId, podId, clusterId, ScopeType.CLUSTER); if (pools.size() == 0) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("No storage pools available for allocation, returning"); - } + if (s_logger.isDebugEnabled()) { + s_logger.debug("No storage pools available for allocation, returning"); + } return suitablePools; } - + Collections.shuffle(pools); - if (s_logger.isDebugEnabled()) { + if (s_logger.isDebugEnabled()) { s_logger.debug("RandomStoragePoolAllocator has " + pools.size() + " pools to check for allocation"); } - for (StoragePoolVO pool: pools) { - if(suitablePools.size() == returnUpTo){ - break; - } - StoragePool pol = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(pool.getId()); - - if (filter(avoid, pol, dskCh, plan)) { - suitablePools.add(pol); - } + for (StoragePoolVO pool : pools) { + if (suitablePools.size() == returnUpTo) { + break; + } + StoragePool pol = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(pool.getId()); + + if (filter(avoid, pol, dskCh, plan)) { + suitablePools.add(pol); + } } if (s_logger.isDebugEnabled()) { - s_logger.debug("RandomStoragePoolAllocator returning "+suitablePools.size() +" suitable storage pools"); + s_logger.debug("RandomStoragePoolAllocator returning " + suitablePools.size() + " suitable storage pools"); } return suitablePools; diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index bc64250d8f8..52595a1bc94 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -24,8 +24,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; @@ -45,10 +43,10 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; @@ -57,8 +55,6 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; -import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -74,43 +70,42 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.swift.SwiftManager; import com.cloud.user.Account; import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.UserVmVO; -import com.cloud.vm.dao.UserVmDao; public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { - private static final Logger s_logger = Logger - .getLogger(CloudStackImageStoreDriverImpl.class); + private static final Logger s_logger = Logger.getLogger(CloudStackImageStoreDriverImpl.class); @Inject VMTemplateZoneDao templateZoneDao; @Inject VMTemplateDao templateDao; - @Inject DownloadMonitor _downloadMonitor; - @Inject VolumeDao volumeDao; - @Inject VolumeDataStoreDao _volumeStoreDao; - @Inject HostDao hostDao; - @Inject SnapshotDao snapshotDao; - @Inject AgentManager agentMgr; - @Inject SnapshotManager snapshotMgr; - @Inject - private SwiftManager _swiftMgr; @Inject - private S3Manager _s3Mgr; - @Inject AccountDao _accountDao; + DownloadMonitor _downloadMonitor; + @Inject + VolumeDao volumeDao; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + HostDao hostDao; + @Inject + SnapshotDao snapshotDao; + @Inject + AgentManager agentMgr; + @Inject + SnapshotManager snapshotMgr; + @Inject + AccountDao _accountDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject - private AgentManager _agentMgr; - @Inject TemplateDataStoreDao _templateStoreDao; - @Inject EndPointSelector _epSelector; - @Inject DataStoreManager _dataStoreMgr; - + TemplateDataStoreDao _templateStoreDao; + @Inject + EndPointSelector _epSelector; + @Inject + DataStoreManager _dataStoreMgr; @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -123,10 +118,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { return null; } - @Override public DataStoreTO getStoreTO(DataStore store) { - ImageStoreImpl nfsStore = (ImageStoreImpl)store; + ImageStoreImpl nfsStore = (ImageStoreImpl) store; NfsTO nfsTO = new NfsTO(); nfsTO.setRole(store.getRole()); nfsTO.setUrl(nfsStore.getUri()); @@ -147,23 +141,21 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { class CreateContext extends AsyncRpcConext { final DataObject data; + public CreateContext(AsyncCompletionCallback callback, DataObject data) { super(callback); this.data = data; } } - @Override - public void createAsync(DataObject data, - AsyncCompletionCallback callback) { - CreateContext context = new CreateContext(callback, data); - AsyncCallbackDispatcher caller = - AsyncCallbackDispatcher.create(this); + public void createAsync(DataObject data, AsyncCompletionCallback callback) { + CreateContext context = new CreateContext(callback, data); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); caller.setContext(context); caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - if (data.getType() == DataObjectType.TEMPLATE) { _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { @@ -171,13 +163,14 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } } - protected Void createAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); + protected Void createAsyncCallback( + AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); - TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(),obj.getId()); + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); if (tmpltStoreVO != null) { TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); @@ -196,27 +189,26 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { templateDao.update(obj.getId(), tmlptUpdater); } - AsyncCompletionCallback caller = context.getParentCallback(); + AsyncCompletionCallback caller = context.getParentCallback(); - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || - answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || - answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - templateDao.update(obj.getId(), templateDaoBuilder); - } + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + if (answer.getCheckSum() != null) { + VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); + templateDaoBuilder.setChecksum(answer.getCheckSum()); + templateDao.update(obj.getId(), templateDaoBuilder); + } - - CreateCmdResult result = new CreateCmdResult(null, answer); - caller.complete(result); - } - return null; + CreateCmdResult result = new CreateCmdResult(null, answer); + caller.complete(result); + } + return null; } private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { @@ -231,22 +223,17 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { DataStore store = _dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getTO(), volumeStore.getVolumeId(), volumeStore.getInstallPath()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(), + volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " - + volumeStore - + " due to " - + ((answer == null) ? "answer is null" : answer - .getDetails())); + s_logger.debug("Failed to delete " + volumeStore + " due to " + + ((answer == null) ? "answer is null" : answer.getDetails())); return; } } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - s_logger.debug("Volume: " + vol.getName() - + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException( - "Please specify a volume that is not currently being uploaded."); + s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); + throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); } CommandResult result = new CommandResult(); @@ -275,8 +262,9 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { // TODO: need to understand why we need to mark destroyed in // template_store_ref table here instead of in callback. - // Currently I did that in callback, so I removed previous code to mark template_host_ref - if ( sZoneId != null ){ + // Currently I did that in callback, so I removed previous code to mark + // template_host_ref + if (sZoneId != null) { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } @@ -284,85 +272,83 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), + template.getAccountId()); + EndPoint ep = _epSelector.select(templateObj); + Answer answer = ep.sendMessage(cmd); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - result.setSuccess(false); - result.setResult("Delete template failed"); - callback.complete(result); + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSuccess(false); + result.setResult("Delete template failed"); + callback.complete(result); - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - result.setSuccess(true); - callback.complete(result); - } + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSuccess(true); + callback.complete(result); + } - List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } - } + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } } - } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - SnapshotObject snapshotObj = (SnapshotObject)data; + SnapshotObject snapshotObj = (SnapshotObject) data; DataStore secStore = snapshotObj.getDataStore(); CommandResult result = new CommandResult(); - SnapshotVO snapshot = snapshotObj.getSnapshotVO(); + SnapshotVO snapshot = snapshotObj.getSnapshotVO(); - if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotObj.getId() + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotObj.getId()); - callback.complete(result); - return; - } + if (snapshot == null) { + s_logger.debug("Destroying snapshot " + snapshotObj.getId() + + " backup failed due to unable to find snapshot "); + result.setResult("Unable to find snapshot: " + snapshotObj.getId()); + callback.complete(result); + return; + } - try { + try { String backupOfSnapshot = snapshotObj.getPath(); if (backupOfSnapshot == null) { callback.complete(result); return; } - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2( - secStore.getTO(), backupOfSnapshot); - EndPoint ep = _epSelector.select(secStore); - Answer answer = ep.sendMessage(cmd); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot); + EndPoint ep = _epSelector.select(secStore); + Answer answer = ep.sendMessage(cmd); - if (answer != null && !answer.getResult()) { - result.setResult(answer.getDetails()); - } - } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); - result.setResult(e.toString()); - } - callback.complete(result); + if (answer != null && !answer.getResult()) { + result.setResult(answer.getDetails()); + } + } catch (Exception e) { + s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); + result.setResult(e.toString()); + } + callback.complete(result); } @Override - public void deleteAsync(DataObject data, - AsyncCompletionCallback callback) { + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.VOLUME) { deleteVolume(data, callback); } else if (data.getType() == DataObjectType.TEMPLATE) { deleteTemplate(data, callback); } else if (data.getType() == DataObjectType.SNAPSHOT) { - deleteSnapshot(data, callback); + deleteSnapshot(data, callback); } } @Override - public void copyAsync(DataObject srcdata, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub } @@ -373,11 +359,10 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { return false; } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java index d550f0b3b48..a0b64bfc893 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java @@ -18,7 +18,6 @@ package org.apache.cloudstack.storage.datastore.lifecycle; import java.net.URI; import java.net.URISyntaxException; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,56 +36,51 @@ import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.exception.DiscoveryException; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase; import com.cloud.resource.Discoverer; -import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; -import com.cloud.resource.ServerResource; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.utils.UriUtils; public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { - private static final Logger s_logger = Logger - .getLogger(CloudStackImageStoreLifeCycleImpl.class); + private static final Logger s_logger = Logger.getLogger(CloudStackImageStoreLifeCycleImpl.class); @Inject protected ResourceManager _resourceMgr; @Inject - protected ImageStoreDao imageStoreDao; - @Inject - ImageStoreHelper imageStoreHelper; - @Inject - ImageStoreProviderManager imageStoreMgr; + protected ImageStoreDao imageStoreDao; + @Inject + ImageStoreHelper imageStoreHelper; + @Inject + ImageStoreProviderManager imageStoreMgr; protected List _discoverers; + public List getDiscoverers() { return _discoverers; } + public void setDiscoverers(List _discoverers) { this._discoverers = _discoverers; } - public CloudStackImageStoreLifeCycleImpl() { - } - + public CloudStackImageStoreLifeCycleImpl() { + } + @SuppressWarnings("unchecked") @Override public DataStore initialize(Map dsInfos) { Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); - String name = (String)dsInfos.get("name"); - if ( name == null ){ + String name = (String) dsInfos.get("name"); + if (name == null) { name = url; } - String providerName = (String)dsInfos.get("providerName"); - DataStoreRole role =(DataStoreRole) dsInfos.get("role"); - Map details = (Map)dsInfos.get("details"); + String providerName = (String) dsInfos.get("providerName"); + DataStoreRole role = (DataStoreRole) dsInfos.get("role"); + Map details = (Map) dsInfos.get("details"); s_logger.info("Trying to add a new host at " + url + " in data center " + dcId); @@ -94,91 +88,81 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { try { uri = new URI(UriUtils.encodeURIComponent(url)); if (uri.getScheme() == null) { - throw new InvalidParameterValueException("uri.scheme is null " - + url + ", add nfs:// as a prefix"); + throw new InvalidParameterValueException("uri.scheme is null " + url + ", add nfs:// as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("nfs")) { - if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") - || uri.getPath() == null + if (uri.getHost() == null || uri.getHost().equalsIgnoreCase("") || uri.getPath() == null || uri.getPath().equalsIgnoreCase("")) { throw new InvalidParameterValueException( "Your host and/or path is wrong. Make sure it's of the format nfs://hostname/path"); } } } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url - + " is not a valid uri"); + throw new InvalidParameterValueException(url + " is not a valid uri"); } - if ( dcId == null ){ - throw new InvalidParameterValueException("DataCenter id is null, and cloudstack default image storehas to be associated with a data center"); + if (dcId == null) { + throw new InvalidParameterValueException( + "DataCenter id is null, and cloudstack default image storehas to be associated with a data center"); } - Map imageStoreParameters = new HashMap(); imageStoreParameters.put("name", name); imageStoreParameters.put("zoneId", dcId); imageStoreParameters.put("url", url); imageStoreParameters.put("protocol", uri.getScheme().toLowerCase()); - imageStoreParameters.put("scope", ScopeType.ZONE); // default cloudstack provider only supports zone-wide image store + imageStoreParameters.put("scope", ScopeType.ZONE); // default cloudstack + // provider only + // supports zone-wide + // image store imageStoreParameters.put("providerName", providerName); imageStoreParameters.put("role", role); - ImageStoreVO ids = imageStoreHelper.createImageStore(imageStoreParameters, details); return imageStoreMgr.getImageStore(ids.getId()); } - @Override public boolean attachCluster(DataStore store, ClusterScope scope) { // TODO Auto-generated method stub return false; } - @Override - public boolean attachHost(DataStore store, HostScope scope, - StoragePoolInfo existingInfo) { + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { // TODO Auto-generated method stub return false; } - @Override public boolean attachZone(DataStore dataStore, ZoneScope scope) { // TODO Auto-generated method stub return false; } - @Override public boolean dettach() { // TODO Auto-generated method stub return false; } - @Override public boolean unmanaged() { // TODO Auto-generated method stub return false; } - @Override public boolean maintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean cancelMaintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean deleteDataStore(DataStore store) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java index c9952e2a66d..23de36fb952 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackImageStoreProviderImpl.java @@ -82,7 +82,7 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { @Override public Set getTypes() { - Set types = new HashSet(); + Set types = new HashSet(); types.add(DataStoreProviderType.IMAGE); types.add(DataStoreProviderType.ImageCache); return types; @@ -90,15 +90,14 @@ public class CloudStackImageStoreProviderImpl implements ImageStoreProvider { @Override public boolean isScopeSupported(ScopeType scope) { - if ( scope == ScopeType.ZONE) + if (scope == ScopeType.ZONE) return true; return false; } @Override public boolean needDownloadSysTemplate() { - return false; + return false; } - } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 1798ded4d05..0a2a84064e7 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -25,8 +25,6 @@ import java.util.Set; import javax.inject.Inject; -import org.apache.log4j.Logger; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; @@ -48,10 +46,10 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; +import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; @@ -61,7 +59,6 @@ import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.S3TO; import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -77,46 +74,49 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.s3.S3Manager; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.swift.SwiftManager; import com.cloud.user.Account; import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; public class S3ImageStoreDriverImpl implements ImageStoreDriver { - private static final Logger s_logger = Logger - .getLogger(S3ImageStoreDriverImpl.class); + private static final Logger s_logger = Logger.getLogger(S3ImageStoreDriverImpl.class); @Inject VMTemplateZoneDao templateZoneDao; @Inject VMTemplateDao templateDao; - @Inject DownloadMonitor _downloadMonitor; + @Inject + DownloadMonitor _downloadMonitor; @Inject ImageStoreDetailsDao _imageStoreDetailsDao; - @Inject VolumeDao volumeDao; - @Inject VolumeDataStoreDao _volumeStoreDao; - @Inject HostDao hostDao; - @Inject SnapshotDao snapshotDao; - @Inject AgentManager agentMgr; - @Inject SnapshotManager snapshotMgr; - @Inject - private SwiftManager _swiftMgr; @Inject - private S3Manager _s3Mgr; - @Inject AccountDao _accountDao; - @Inject UserVmDao _userVmDao; - @Inject UserVmJoinDao _userVmJoinDao; + VolumeDao volumeDao; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + HostDao hostDao; + @Inject + SnapshotDao snapshotDao; + @Inject + AgentManager agentMgr; + @Inject + SnapshotManager snapshotMgr; + @Inject + AccountDao _accountDao; + @Inject + UserVmDao _userVmDao; + @Inject + UserVmJoinDao _userVmJoinDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject - private AgentManager _agentMgr; - @Inject TemplateDataStoreDao _templateStoreDao; - @Inject EndPointSelector _epSelector; - @Inject DataStoreManager _dataStoreMgr; + TemplateDataStoreDao _templateStoreDao; + @Inject + EndPointSelector _epSelector; + @Inject + DataStoreManager _dataStoreMgr; @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -129,20 +129,20 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { return null; } - @Override public DataStoreTO getStoreTO(DataStore store) { - ImageStoreImpl imgStore = (ImageStoreImpl)store; + ImageStoreImpl imgStore = (ImageStoreImpl) store; Map details = _imageStoreDetailsDao.getDetails(imgStore.getId()); return new S3TO(imgStore.getId(), imgStore.getUuid(), details.get(ApiConstants.S3_ACCESS_KEY), - details.get(ApiConstants.S3_SECRET_KEY), - details.get(ApiConstants.S3_END_POINT), - details.get(ApiConstants.S3_BUCKET_NAME), - details.get(ApiConstants.S3_HTTPS_FLAG) == null ? false : Boolean.parseBoolean(details.get(ApiConstants.S3_HTTPS_FLAG)), - details.get(ApiConstants.S3_CONNECTION_TIMEOUT) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_CONNECTION_TIMEOUT)), - details.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_MAX_ERROR_RETRY)), - details.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null : Integer.valueOf(details.get(ApiConstants.S3_SOCKET_TIMEOUT)), - imgStore.getCreated()); + details.get(ApiConstants.S3_SECRET_KEY), details.get(ApiConstants.S3_END_POINT), + details.get(ApiConstants.S3_BUCKET_NAME), details.get(ApiConstants.S3_HTTPS_FLAG) == null ? false + : Boolean.parseBoolean(details.get(ApiConstants.S3_HTTPS_FLAG)), + details.get(ApiConstants.S3_CONNECTION_TIMEOUT) == null ? null : Integer.valueOf(details + .get(ApiConstants.S3_CONNECTION_TIMEOUT)), + details.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null : Integer.valueOf(details + .get(ApiConstants.S3_MAX_ERROR_RETRY)), + details.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null : Integer.valueOf(details + .get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated()); } @@ -160,6 +160,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { class CreateContext extends AsyncRpcConext { final DataObject data; + public CreateContext(AsyncCompletionCallback callback, DataObject data) { super(callback); this.data = data; @@ -167,16 +168,13 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } @Override - public void createAsync(DataObject data, - AsyncCompletionCallback callback) { + public void createAsync(DataObject data, AsyncCompletionCallback callback) { CreateContext context = new CreateContext(callback, data); - AsyncCallbackDispatcher caller = - AsyncCallbackDispatcher.create(this); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - if (data.getType() == DataObjectType.TEMPLATE) { _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { @@ -196,22 +194,17 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { DataStore store = _dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getTO(), volumeStore.getVolumeId(), volumeStore.getInstallPath()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(), + volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " - + volumeStore - + " due to " - + ((answer == null) ? "answer is null" : answer - .getDetails())); + s_logger.debug("Failed to delete " + volumeStore + " due to " + + ((answer == null) ? "answer is null" : answer.getDetails())); return; } } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - s_logger.debug("Volume: " + vol.getName() - + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException( - "Please specify a volume that is not currently being uploaded."); + s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); + throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); } _volumeStoreDao.remove(volumeStore.getId()); volumeDao.remove(vol.getId()); @@ -221,14 +214,13 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } } - protected Void createAsyncCallback(AsyncCallbackDispatcher callback, CreateContext context) { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; DataStore store = obj.getDataStore(); - TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(),obj.getId()); + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); if (tmpltStoreVO != null) { TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); @@ -249,9 +241,9 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { AsyncCompletionCallback caller = context.getParentCallback(); - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || - answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || - answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { CreateCmdResult result = new CreateCmdResult(null, null); result.setSuccess(false); result.setResult(answer.getErrorString()); @@ -263,7 +255,6 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { templateDao.update(obj.getId(), templateDaoBuilder); } - CreateCmdResult result = new CreateCmdResult(null, null); caller.complete(result); } @@ -287,8 +278,8 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { eventType = EventTypes.EVENT_TEMPLATE_DELETE; } - if ( sZoneId != null ){ - //TODO: how to handle region wide usage data where sZoneId == null + if (sZoneId != null) { + // TODO: how to handle region wide usage data where sZoneId == null UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } @@ -296,7 +287,8 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), + template.getAccountId()); EndPoint ep = _epSelector.select(templateObj); Answer answer = ep.sendMessage(cmd); @@ -325,13 +317,14 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - SnapshotObject snapshotObj = (SnapshotObject)data; + SnapshotObject snapshotObj = (SnapshotObject) data; DataStore secStore = snapshotObj.getDataStore(); CommandResult result = new CommandResult(); SnapshotVO snapshot = snapshotObj.getSnapshotVO(); if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotObj.getId() + " backup failed due to unable to find snapshot "); + s_logger.debug("Destroying snapshot " + snapshotObj.getId() + + " backup failed due to unable to find snapshot "); result.setResult("Unable to find snapshot: " + snapshotObj.getId()); callback.complete(result); return; @@ -345,8 +338,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { return; } - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2( - secStore.getTO(), backupOfSnapshot); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot); EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); @@ -360,22 +352,19 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { callback.complete(result); } - @Override - public void deleteAsync(DataObject data, - AsyncCompletionCallback callback) { + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.VOLUME) { deleteVolume(data, callback); } else if (data.getType() == DataObjectType.TEMPLATE) { deleteTemplate(data, callback); } else if (data.getType() == DataObjectType.SNAPSHOT) { - deleteSnapshot(data, callback); + deleteSnapshot(data, callback); } } @Override - public void copyAsync(DataObject srcdata, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub } @@ -386,11 +375,10 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { return false; } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java index 4ea97e57bfc..674a13d854d 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -16,9 +16,6 @@ // under the License. package org.apache.cloudstack.storage.datastore.lifecycle; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,69 +35,58 @@ import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.exception.DiscoveryException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase; import com.cloud.resource.Discoverer; -import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; -import com.cloud.resource.ServerResource; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; import com.cloud.storage.s3.S3Manager; -import com.cloud.utils.UriUtils; public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { - private static final Logger s_logger = Logger - .getLogger(S3ImageStoreLifeCycleImpl.class); + private static final Logger s_logger = Logger.getLogger(S3ImageStoreLifeCycleImpl.class); @Inject protected ResourceManager _resourceMgr; @Inject - protected ImageStoreDao imageStoreDao; - @Inject - ImageStoreHelper imageStoreHelper; - @Inject - ImageStoreProviderManager imageStoreMgr; + protected ImageStoreDao imageStoreDao; @Inject - S3Manager _s3Mgr; + ImageStoreHelper imageStoreHelper; + @Inject + ImageStoreProviderManager imageStoreMgr; + @Inject + S3Manager _s3Mgr; protected List _discoverers; + public List getDiscoverers() { return _discoverers; } + public void setDiscoverers(List _discoverers) { this._discoverers = _discoverers; } - public S3ImageStoreLifeCycleImpl() { - } - + public S3ImageStoreLifeCycleImpl() { + } + @SuppressWarnings("unchecked") @Override public DataStore initialize(Map dsInfos) { Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); - String name = (String)dsInfos.get("name"); - String providerName = (String)dsInfos.get("providerName"); - ScopeType scope = (ScopeType)dsInfos.get("scope"); - DataStoreRole role =(DataStoreRole) dsInfos.get("role"); - Map details = (Map)dsInfos.get("details"); + String name = (String) dsInfos.get("name"); + String providerName = (String) dsInfos.get("providerName"); + ScopeType scope = (ScopeType) dsInfos.get("scope"); + DataStoreRole role = (DataStoreRole) dsInfos.get("role"); + Map details = (Map) dsInfos.get("details"); s_logger.info("Trying to add a S3 store in data center " + dcId); /* - try{ - // verify S3 parameters - _s3Mgr.verifyS3Fields(details); - } - catch (DiscoveryException ex){ - throw new InvalidParameterValueException("failed to verify S3 parameters!"); - } - */ + * try{ // verify S3 parameters _s3Mgr.verifyS3Fields(details); } catch + * (DiscoveryException ex){ throw new + * InvalidParameterValueException("failed to verify S3 parameters!"); } + */ Map imageStoreParameters = new HashMap(); imageStoreParameters.put("name", name); @@ -108,7 +94,7 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { imageStoreParameters.put("url", url); String protocol = "http"; String useHttps = details.get(ApiConstants.S3_HTTPS_FLAG); - if (useHttps != null && Boolean.parseBoolean(useHttps)){ + if (useHttps != null && Boolean.parseBoolean(useHttps)) { protocol = "https"; } imageStoreParameters.put("protocol", protocol); @@ -124,57 +110,48 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { return imageStoreMgr.getImageStore(ids.getId()); } - @Override public boolean attachCluster(DataStore store, ClusterScope scope) { // TODO Auto-generated method stub return false; } - @Override - public boolean attachHost(DataStore store, HostScope scope, - StoragePoolInfo existingInfo) { + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { // TODO Auto-generated method stub return false; } - @Override public boolean attachZone(DataStore dataStore, ZoneScope scope) { // TODO Auto-generated method stub return false; } - @Override public boolean dettach() { // TODO Auto-generated method stub return false; } - @Override public boolean unmanaged() { // TODO Auto-generated method stub return false; } - @Override public boolean maintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean cancelMaintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean deleteDataStore(DataStore store) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java index 7efb59a6956..8bcdb44f9c0 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/provider/S3ImageStoreProviderImpl.java @@ -18,12 +18,9 @@ */ package org.apache.cloudstack.storage.datastore.provider; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.UUID; - import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; @@ -83,22 +80,21 @@ public class S3ImageStoreProviderImpl implements ImageStoreProvider { @Override public Set getTypes() { - Set types = new HashSet(); + Set types = new HashSet(); types.add(DataStoreProviderType.IMAGE); return types; } @Override public boolean isScopeSupported(ScopeType scope) { - if ( scope == ScopeType.REGION ) + if (scope == ScopeType.REGION) return true; return false; } @Override public boolean needDownloadSysTemplate() { - return true; + return true; } - } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index 2c7ba1117b4..27e60816155 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -45,6 +45,7 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { EndPointSelector selector; @Inject VMTemplateDao imageDataDao; + public SampleImageStoreDriverImpl() { } @@ -53,7 +54,6 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { return null; } - @Override public DataStoreTO getStoreTO(DataStore store) { // TODO Auto-generated method stub @@ -78,9 +78,8 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { } @Override - public void createAsync(DataObject data, - AsyncCompletionCallback callback) { - //for default http data store, can create http based template/iso + public void createAsync(DataObject data, AsyncCompletionCallback callback) { + // for default http data store, can create http based template/iso CreateCmdResult result = new CreateCmdResult("", null); if (!data.getUri().startsWith("http")) { result.setResult("can't register an image which is not a http link"); @@ -89,7 +88,8 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { } if (data.getSize() == null && data.getType() == DataObjectType.TEMPLATE) { - //the template size is unknown during registration, need to find out the size of template + // the template size is unknown during registration, need to find + // out the size of template EndPoint ep = selector.select(data); if (ep == null) { result.setResult("can't find storage client for:" + data.getId() + "," + data.getType()); @@ -97,9 +97,9 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { return; } CreateObjectCommand createCmd = new CreateObjectCommand(data.getTO()); - CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd); + CreateObjectAnswer answer = (CreateObjectAnswer) ep.sendMessage(createCmd); if (answer.getResult()) { - //update imagestorevo + // update imagestorevo result = new CreateCmdResult(null, null); } else { @@ -112,8 +112,7 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { } @Override - public void deleteAsync(DataObject data, - AsyncCompletionCallback callback) { + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { CommandResult result = new CommandResult(); callback.complete(result); } @@ -125,16 +124,14 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { } @Override - public void copyAsync(DataObject srcdata, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java index fbe9f196a9f..e001c0b4940 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java @@ -34,14 +34,14 @@ import com.cloud.agent.api.StoragePoolInfo; public class SampleImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Inject - protected ImageStoreDao imageStoreDao; - @Inject - ImageStoreHelper imageStoreHelper; - @Inject - ImageStoreProviderManager imageStoreMgr; - public SampleImageStoreLifeCycleImpl() { - } + protected ImageStoreDao imageStoreDao; + @Inject + ImageStoreHelper imageStoreHelper; + @Inject + ImageStoreProviderManager imageStoreMgr; + public SampleImageStoreLifeCycleImpl() { + } @Override public DataStore initialize(Map dsInfos) { @@ -49,57 +49,48 @@ public class SampleImageStoreLifeCycleImpl implements ImageStoreLifeCycle { return imageStoreMgr.getImageStore(ids.getId()); } - @Override public boolean attachCluster(DataStore store, ClusterScope scope) { // TODO Auto-generated method stub return false; } - @Override - public boolean attachHost(DataStore store, HostScope scope, - StoragePoolInfo existingInfo) { + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { // TODO Auto-generated method stub return false; } - @Override public boolean attachZone(DataStore dataStore, ZoneScope scope) { // TODO Auto-generated method stub return false; } - @Override public boolean dettach() { // TODO Auto-generated method stub return false; } - @Override public boolean unmanaged() { // TODO Auto-generated method stub return false; } - @Override public boolean maintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean cancelMaintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean deleteDataStore(DataStore store) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index 1a0614b5e66..c0c55d667d1 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -46,6 +46,7 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { ImageStoreProviderManager storeMgr; long id; String uuid; + @Override public DataStoreLifeCycle getDataStoreLifeCycle() { return lifeCycle; @@ -67,7 +68,7 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { @Override public Set getTypes() { - Set types = new HashSet(); + Set types = new HashSet(); types.add(DataStoreProviderType.IMAGE); return types; } @@ -84,7 +85,7 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { @Override public boolean isScopeSupported(ScopeType scope) { - if ( scope == ScopeType.ZONE) + if (scope == ScopeType.ZONE) return true; return false; } @@ -94,5 +95,4 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { return false; } - } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index cdfe63e38ac..71b18d557cc 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -50,7 +50,6 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; @@ -60,7 +59,6 @@ import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.SwiftTO; import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.api.query.vo.UserVmJoinVO; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; @@ -83,40 +81,50 @@ import com.cloud.storage.swift.SwiftManager; import com.cloud.user.Account; import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.UserVmVO; import com.cloud.vm.dao.UserVmDao; public class SwiftImageStoreDriverImpl implements ImageStoreDriver { - private static final Logger s_logger = Logger - .getLogger(SwiftImageStoreDriverImpl.class); + private static final Logger s_logger = Logger.getLogger(SwiftImageStoreDriverImpl.class); @Inject VMTemplateZoneDao templateZoneDao; @Inject VMTemplateDao templateDao; - @Inject DownloadMonitor _downloadMonitor; + @Inject + DownloadMonitor _downloadMonitor; @Inject ImageStoreDetailsDao _imageStoreDetailsDao; - @Inject VolumeDao volumeDao; - @Inject VolumeDataStoreDao _volumeStoreDao; - @Inject HostDao hostDao; - @Inject SnapshotDao snapshotDao; - @Inject AgentManager agentMgr; - @Inject SnapshotManager snapshotMgr; - @Inject + @Inject + VolumeDao volumeDao; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + HostDao hostDao; + @Inject + SnapshotDao snapshotDao; + @Inject + AgentManager agentMgr; + @Inject + SnapshotManager snapshotMgr; + @Inject private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; - @Inject AccountDao _accountDao; - @Inject UserVmDao _userVmDao; - @Inject UserVmJoinDao _userVmJoinDao; + @Inject + AccountDao _accountDao; + @Inject + UserVmDao _userVmDao; + @Inject + UserVmJoinDao _userVmJoinDao; @Inject SecondaryStorageVmManager _ssvmMgr; @Inject private AgentManager _agentMgr; - @Inject TemplateDataStoreDao _templateStoreDao; - @Inject EndPointSelector _epSelector; - @Inject DataStoreManager _dataStoreMgr; - + @Inject + TemplateDataStoreDao _templateStoreDao; + @Inject + EndPointSelector _epSelector; + @Inject + DataStoreManager _dataStoreMgr; @Override public String grantAccess(DataObject data, EndPoint ep) { @@ -129,14 +137,12 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { return null; } - @Override public DataStoreTO getStoreTO(DataStore store) { - ImageStoreImpl imgStore = (ImageStoreImpl)store; + ImageStoreImpl imgStore = (ImageStoreImpl) store; Map details = _imageStoreDetailsDao.getDetails(imgStore.getId()); return new SwiftTO(imgStore.getId(), imgStore.getUri(), details.get(ApiConstants.ACCOUNT), - details.get(ApiConstants.USERNAME), - details.get(ApiConstants.KEY)); + details.get(ApiConstants.USERNAME), details.get(ApiConstants.KEY)); } @Override @@ -153,6 +159,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { class CreateContext extends AsyncRpcConext { final DataObject data; + public CreateContext(AsyncCompletionCallback callback, DataObject data) { super(callback); this.data = data; @@ -160,15 +167,13 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } @Override - public void createAsync(DataObject data, - AsyncCompletionCallback callback) { + public void createAsync(DataObject data, AsyncCompletionCallback callback) { CreateContext context = new CreateContext(callback, data); - AsyncCallbackDispatcher caller = - AsyncCallbackDispatcher.create(this); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); caller.setContext(context); caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - if (data.getType() == DataObjectType.TEMPLATE) { _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { @@ -182,7 +187,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { DataObject obj = context.data; DataStore store = obj.getDataStore(); - TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(),obj.getId()); + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); if (tmpltStoreVO != null) { TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); updateBuilder.setDownloadPercent(answer.getDownloadPct()); @@ -203,11 +208,11 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { AsyncCompletionCallback caller = context.getParentCallback(); - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR || - answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || - answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { CreateCmdResult result = new CreateCmdResult(null, null); - //result.setSucess(false); + // result.setSucess(false); result.setResult(answer.getErrorString()); caller.complete(result); } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { @@ -217,7 +222,6 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { templateDao.update(obj.getId(), templateDaoBuilder); } - CreateCmdResult result = new CreateCmdResult(null, null); caller.complete(result); } @@ -237,22 +241,17 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand( - store.getTO(), volumeStore.getVolumeId(), volumeStore.getInstallPath()); + DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(), + volumeStore.getInstallPath()); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " - + volumeStore - + " due to " - + ((answer == null) ? "answer is null" : answer - .getDetails())); + s_logger.debug("Failed to delete " + volumeStore + " due to " + + ((answer == null) ? "answer is null" : answer.getDetails())); return; } } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - s_logger.debug("Volume: " + vol.getName() - + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException( - "Please specify a volume that is not currently being uploaded."); + s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); + throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); } _volumeStoreDao.remove(volumeStore.getId()); volumeDao.remove(vol.getId()); @@ -281,8 +280,9 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { // TODO: need to understand why we need to mark destroyed in // template_store_ref table here instead of in callback. - // Currently I did that in callback, so I removed previous code to mark template_host_ref - if (sZoneId != null){ + // Currently I did that in callback, so I removed previous code to mark + // template_host_ref + if (sZoneId != null) { UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); } @@ -290,7 +290,8 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); String installPath = tmplStore.getInstallPath(); if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), template.getAccountId()); + DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), + template.getAccountId()); EndPoint ep = _epSelector.select(templateObj); Answer answer = ep.sendMessage(cmd); @@ -316,16 +317,17 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } } } - } + } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - SnapshotObject snapshotObj = (SnapshotObject)data; + SnapshotObject snapshotObj = (SnapshotObject) data; DataStore secStore = snapshotObj.getDataStore(); CommandResult result = new CommandResult(); SnapshotVO snapshot = snapshotObj.getSnapshotVO(); if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotObj.getId() + " backup failed due to unable to find snapshot "); + s_logger.debug("Destroying snapshot " + snapshotObj.getId() + + " backup failed due to unable to find snapshot "); result.setResult("Unable to find snapshot: " + snapshotObj.getId()); callback.complete(result); return; @@ -338,8 +340,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { return; } - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2( - secStore.getTO(), backupOfSnapshot); + DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot); EndPoint ep = _epSelector.select(secStore); Answer answer = ep.sendMessage(cmd); @@ -354,20 +355,18 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } @Override - public void deleteAsync(DataObject data, - AsyncCompletionCallback callback) { + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { if (data.getType() == DataObjectType.VOLUME) { deleteVolume(data, callback); } else if (data.getType() == DataObjectType.TEMPLATE) { deleteTemplate(data, callback); } else if (data.getType() == DataObjectType.SNAPSHOT) { - deleteSnapshot(data, callback); + deleteSnapshot(data, callback); } } @Override - public void copyAsync(DataObject srcdata, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub } @@ -378,11 +377,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { return false; } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java index 3fc68a1e8fe..3ba3b3133d0 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -16,9 +16,6 @@ // under the License. package org.apache.cloudstack.storage.datastore.lifecycle; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -37,55 +34,47 @@ import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.exception.DiscoveryException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.host.Host; -import com.cloud.host.HostVO; -import com.cloud.hypervisor.kvm.discoverer.KvmDummyResourceBase; import com.cloud.resource.Discoverer; -import com.cloud.resource.ResourceListener; import com.cloud.resource.ResourceManager; -import com.cloud.resource.ServerResource; import com.cloud.storage.DataStoreRole; import com.cloud.storage.ScopeType; -import com.cloud.utils.UriUtils; public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { - private static final Logger s_logger = Logger - .getLogger(SwiftImageStoreLifeCycleImpl.class); + private static final Logger s_logger = Logger.getLogger(SwiftImageStoreLifeCycleImpl.class); @Inject protected ResourceManager _resourceMgr; @Inject - protected ImageStoreDao imageStoreDao; - @Inject - ImageStoreHelper imageStoreHelper; - @Inject - ImageStoreProviderManager imageStoreMgr; + protected ImageStoreDao imageStoreDao; + @Inject + ImageStoreHelper imageStoreHelper; + @Inject + ImageStoreProviderManager imageStoreMgr; protected List _discoverers; + public List getDiscoverers() { return _discoverers; } + public void setDiscoverers(List _discoverers) { this._discoverers = _discoverers; } - public SwiftImageStoreLifeCycleImpl() { - } - + public SwiftImageStoreLifeCycleImpl() { + } @Override public DataStore initialize(Map dsInfos) { Long dcId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); - String name = (String)dsInfos.get("name"); - ScopeType scope = (ScopeType)dsInfos.get("scope"); - String providerName = (String)dsInfos.get("providerName"); - DataStoreRole role =(DataStoreRole) dsInfos.get("role"); + String name = (String) dsInfos.get("name"); + ScopeType scope = (ScopeType) dsInfos.get("scope"); + String providerName = (String) dsInfos.get("providerName"); + DataStoreRole role = (DataStoreRole) dsInfos.get("role"); - Map details = (Map)dsInfos.get("details"); + Map details = (Map) dsInfos.get("details"); s_logger.info("Trying to add a swift store at " + url + " in data center " + dcId); @@ -107,57 +96,48 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { return imageStoreMgr.getImageStore(ids.getId()); } - @Override public boolean attachCluster(DataStore store, ClusterScope scope) { // TODO Auto-generated method stub return false; } - @Override - public boolean attachHost(DataStore store, HostScope scope, - StoragePoolInfo existingInfo) { + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { // TODO Auto-generated method stub return false; } - @Override public boolean attachZone(DataStore dataStore, ZoneScope scope) { // TODO Auto-generated method stub return false; } - @Override public boolean dettach() { // TODO Auto-generated method stub return false; } - @Override public boolean unmanaged() { // TODO Auto-generated method stub return false; } - @Override public boolean maintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean cancelMaintain(DataStore store) { // TODO Auto-generated method stub return false; } - @Override public boolean deleteDataStore(DataStore store) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java index bd6f9f0c9f8..788eebcd145 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/provider/SwiftImageStoreProviderImpl.java @@ -82,22 +82,21 @@ public class SwiftImageStoreProviderImpl implements ImageStoreProvider { @Override public Set getTypes() { - Set types = new HashSet(); + Set types = new HashSet(); types.add(DataStoreProviderType.IMAGE); return types; } @Override public boolean isScopeSupported(ScopeType scope) { - if ( scope == ScopeType.REGION ) + if (scope == ScopeType.REGION) return true; return false; } @Override public boolean needDownloadSysTemplate() { - return true; + return true; } - } diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index e801429fcd6..4c2f3894ef2 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -60,185 +60,186 @@ import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.vm.dao.VMInstanceDao; public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { - private static final Logger s_logger = Logger - .getLogger(CloudStackPrimaryDataStoreDriverImpl.class); - @Inject DiskOfferingDao diskOfferingDao; - @Inject VMTemplateDao templateDao; - @Inject VolumeDao volumeDao; - @Inject HostDao hostDao; - @Inject StorageManager storageMgr; - @Inject VolumeManager volumeMgr; - @Inject VMInstanceDao vmDao; - @Inject SnapshotDao snapshotDao; - @Inject PrimaryDataStoreDao primaryStoreDao; - @Inject SnapshotManager snapshotMgr; - @Inject EndPointSelector epSelector; - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } + private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class); + @Inject + DiskOfferingDao diskOfferingDao; + @Inject + VMTemplateDao templateDao; + @Inject + VolumeDao volumeDao; + @Inject + HostDao hostDao; + @Inject + StorageManager storageMgr; + @Inject + VolumeManager volumeMgr; + @Inject + VMInstanceDao vmDao; + @Inject + SnapshotDao snapshotDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + @Inject + SnapshotManager snapshotMgr; + @Inject + EndPointSelector epSelector; - @Override + @Override + public String grantAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return null; + } + + @Override public DataTO getTO(DataObject data) { return null; } - - @Override + @Override public DataStoreTO getStoreTO(DataStore store) { // TODO Auto-generated method stub return null; } @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } + public boolean revokeAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return false; + } - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } + @Override + public Set listObjects(DataStore store) { + // TODO Auto-generated method stub + return null; + } - public Answer createVolume( - VolumeInfo volume) throws StorageUnavailableException { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating volume: " + volume); - } + public Answer createVolume(VolumeInfo volume) throws StorageUnavailableException { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating volume: " + volume); + } - CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO()); - EndPoint ep = epSelector.select(volume); - Answer answer = ep.sendMessage(cmd); - return answer; - } + CreateObjectCommand cmd = new CreateObjectCommand(volume.getTO()); + EndPoint ep = epSelector.select(volume); + Answer answer = ep.sendMessage(cmd); + return answer; + } - @Override - public void createAsync(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - String errMsg = null; - Answer answer = null; - if (data.getType() == DataObjectType.VOLUME) { - try { - answer = createVolume((VolumeInfo)data); - } catch (StorageUnavailableException e) { - s_logger.debug("failed to create volume", e); - errMsg = e.toString(); - } catch (Exception e) { - s_logger.debug("failed to create volume", e); - errMsg = e.toString(); - } - } - CreateCmdResult result = new CreateCmdResult(null, answer); - if (errMsg != null) { - result.setResult(errMsg); - } + @Override + public void createAsync(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + String errMsg = null; + Answer answer = null; + if (data.getType() == DataObjectType.VOLUME) { + try { + answer = createVolume((VolumeInfo) data); + } catch (StorageUnavailableException e) { + s_logger.debug("failed to create volume", e); + errMsg = e.toString(); + } catch (Exception e) { + s_logger.debug("failed to create volume", e); + errMsg = e.toString(); + } + } + CreateCmdResult result = new CreateCmdResult(null, answer); + if (errMsg != null) { + result.setResult(errMsg); + } - callback.complete(result); - } - - @Override - public void deleteAsync(DataObject data, - AsyncCompletionCallback callback) { - DeleteCommand cmd = new DeleteCommand(data.getTO()); - - CommandResult result = new CommandResult(); - try { - EndPoint ep = epSelector.select(data); - Answer answer = ep.sendMessage(cmd); - if (answer != null && !answer.getResult()) { - result.setResult(answer.getDetails()); - } - } catch (Exception ex) { - s_logger.debug("Unable to destoy volume" + data.getId(), ex); - result.setResult(ex.toString()); - } - callback.complete(result); - } - - @Override - public void copyAsync(DataObject srcdata, DataObject destData, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } - - @Override - public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void takeSnapshot(SnapshotInfo snapshot, - AsyncCompletionCallback callback) { - CreateCmdResult result = null; - try { - DataTO snapshotTO = snapshot.getTO(); - - CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO); - EndPoint ep = this.epSelector.select(snapshot); - Answer answer = ep.sendMessage(cmd); - - result = new CreateCmdResult(null, answer); - if (answer != null && !answer.getResult()) { - result.setResult(answer.getDetails()); - } - - callback.complete(result); - return; - } catch (Exception e) { - s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); - result = new CreateCmdResult(null, null); - result.setResult(e.toString()); - } callback.complete(result); - } + } - @Override - public void revertSnapshot(SnapshotInfo snapshot, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { + DeleteCommand cmd = new DeleteCommand(data.getTO()); - } + CommandResult result = new CommandResult(); + try { + EndPoint ep = epSelector.select(data); + Answer answer = ep.sendMessage(cmd); + if (answer != null && !answer.getResult()) { + result.setResult(answer.getDetails()); + } + } catch (Exception ex) { + s_logger.debug("Unable to destoy volume" + data.getId(), ex); + result.setResult(ex.toString()); + } + callback.complete(result); + } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - VolumeObject vol = (VolumeObject)data; - StoragePool pool = (StoragePool)data.getDataStore(); - ResizeVolumePayload resizeParameter = (ResizeVolumePayload)vol.getpayload(); + @Override + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand( - vol.getPath(), new StorageFilerTO(pool), vol.getSize(), - resizeParameter.newSize, resizeParameter.shrinkOk, resizeParameter.instanceName); - CreateCmdResult result = new CreateCmdResult(null, null); - try { - ResizeVolumeAnswer answer = (ResizeVolumeAnswer) this.storageMgr.sendToPool(pool, - resizeParameter.hosts, resizeCmd); - if (answer != null && answer.getResult()) { - long finalSize = answer.getNewSize(); - s_logger.debug("Resize: volume started at size " + vol.getSize() - + " and ended at size " + finalSize); + } - vol.setSize(finalSize); - vol.update(); - } else if (answer != null) { - result.setResult(answer.getDetails()); - } else { - s_logger.debug("return a null answer, mark it as failed for unknown reason"); - result.setResult("return a null answer, mark it as failed for unknown reason"); - } + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + // TODO Auto-generated method stub + return false; + } - } catch (Exception e) { - s_logger.debug("sending resize command failed", e); - result.setResult(e.toString()); - } + @Override + public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + CreateCmdResult result = null; + try { + DataTO snapshotTO = snapshot.getTO(); - callback.complete(result); - } + CreateObjectCommand cmd = new CreateObjectCommand(snapshotTO); + EndPoint ep = this.epSelector.select(snapshot); + Answer answer = ep.sendMessage(cmd); + + result = new CreateCmdResult(null, answer); + if (answer != null && !answer.getResult()) { + result.setResult(answer.getDetails()); + } + + callback.complete(result); + return; + } catch (Exception e) { + s_logger.debug("Failed to take snapshot: " + snapshot.getId(), e); + result = new CreateCmdResult(null, null); + result.setResult(e.toString()); + } + callback.complete(result); + } + + @Override + public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + VolumeObject vol = (VolumeObject) data; + StoragePool pool = (StoragePool) data.getDataStore(); + ResizeVolumePayload resizeParameter = (ResizeVolumePayload) vol.getpayload(); + + ResizeVolumeCommand resizeCmd = new ResizeVolumeCommand(vol.getPath(), new StorageFilerTO(pool), vol.getSize(), + resizeParameter.newSize, resizeParameter.shrinkOk, resizeParameter.instanceName); + CreateCmdResult result = new CreateCmdResult(null, null); + try { + ResizeVolumeAnswer answer = (ResizeVolumeAnswer) this.storageMgr.sendToPool(pool, resizeParameter.hosts, + resizeCmd); + if (answer != null && answer.getResult()) { + long finalSize = answer.getNewSize(); + s_logger.debug("Resize: volume started at size " + vol.getSize() + " and ended at size " + finalSize); + + vol.setSize(finalSize); + vol.update(); + } else if (answer != null) { + result.setResult(answer.getDetails()); + } else { + s_logger.debug("return a null answer, mark it as failed for unknown reason"); + result.setResult("return a null answer, mark it as failed for unknown reason"); + } + + } catch (Exception e) { + s_logger.debug("sending resize command failed", e); + result.setResult(e.toString()); + } + + callback.complete(result); + } } diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index e6bdaed7987..693ab01c73b 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -55,8 +55,6 @@ import com.cloud.resource.ResourceManager; import com.cloud.server.ManagementServer; import com.cloud.storage.OCFS2Manager; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.ScopeType; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; import com.cloud.storage.StoragePoolAutomation; @@ -77,10 +75,8 @@ import com.cloud.vm.dao.SecondaryStorageVmDao; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -public class CloudStackPrimaryDataStoreLifeCycleImpl implements - PrimaryDataStoreLifeCycle { - private static final Logger s_logger = Logger - .getLogger(CloudStackPrimaryDataStoreLifeCycleImpl.class); +public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle { + private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreLifeCycleImpl.class); @Inject protected ResourceManager _resourceMgr; protected List _discoverers; @@ -95,7 +91,6 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements @Inject StorageManager storageMgr; - @Inject VolumeDao volumeDao; @Inject @@ -126,16 +121,16 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements @Inject StoragePoolAutomation storagePoolAutmation; + @SuppressWarnings("unchecked") @Override public DataStore initialize(Map dsInfos) { Long clusterId = (Long) dsInfos.get("clusterId"); Long podId = (Long) dsInfos.get("podId"); Long zoneId = (Long) dsInfos.get("zoneId"); String url = (String) dsInfos.get("url"); - String providerName = (String)dsInfos.get("providerName"); + String providerName = (String) dsInfos.get("providerName"); if (clusterId != null && podId == null) { - throw new InvalidParameterValueException( - "Cluster id requires pod id"); + throw new InvalidParameterValueException("Cluster id requires pod id"); } PrimaryDataStoreParameters parameters = new PrimaryDataStoreParameters(); @@ -144,15 +139,12 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements try { uri = new URI(UriUtils.encodeURIComponent(url)); if (uri.getScheme() == null) { - throw new InvalidParameterValueException("scheme is null " - + url + ", add nfs:// as a prefix"); + throw new InvalidParameterValueException("scheme is null " + url + ", add nfs:// as a prefix"); } else if (uri.getScheme().equalsIgnoreCase("nfs")) { String uriHost = uri.getHost(); String uriPath = uri.getPath(); - if (uriHost == null || uriPath == null - || uriHost.trim().isEmpty() || uriPath.trim().isEmpty()) { - throw new InvalidParameterValueException( - "host or path is null, should be nfs://hostname/path"); + if (uriHost == null || uriPath == null || uriHost.trim().isEmpty() || uriPath.trim().isEmpty()) { + throw new InvalidParameterValueException("host or path is null, should be nfs://hostname/path"); } } else if (uri.getScheme().equalsIgnoreCase("sharedMountPoint")) { String uriPath = uri.getPath(); @@ -163,18 +155,15 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements } else if (uri.getScheme().equalsIgnoreCase("rbd")) { String uriPath = uri.getPath(); if (uriPath == null) { - throw new InvalidParameterValueException( - "host or path is null, should be rbd://hostname/pool"); + throw new InvalidParameterValueException("host or path is null, should be rbd://hostname/pool"); } } } catch (URISyntaxException e) { - throw new InvalidParameterValueException(url - + " is not a valid uri"); + throw new InvalidParameterValueException(url + " is not a valid uri"); } String tags = (String) dsInfos.get("tags"); - Map details = (Map) dsInfos - .get("details"); + Map details = (Map) dsInfos.get("details"); parameters.setTags(tags); parameters.setDetails(details); @@ -188,10 +177,8 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements } String userInfo = uri.getUserInfo(); int port = uri.getPort(); - StoragePool pool = null; if (s_logger.isDebugEnabled()) { - s_logger.debug("createPool Params @ scheme - " + scheme - + " storageHost - " + storageHost + " hostPath - " + s_logger.debug("createPool Params @ scheme - " + scheme + " storageHost - " + storageHost + " hostPath - " + hostPath + " port - " + port); } if (scheme.equalsIgnoreCase("nfs")) { @@ -242,8 +229,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements } if (lun != -1) { if (clusterId == null) { - throw new IllegalArgumentException( - "IscsiLUN need to have clusters specified"); + throw new IllegalArgumentException("IscsiLUN need to have clusters specified"); } hostPath.replaceFirst("/", ""); parameters.setType(StoragePoolType.IscsiLUN); @@ -256,14 +242,11 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements try { pools = discoverer.find(zoneId, podId, uri, details); } catch (DiscoveryException e) { - throw new IllegalArgumentException( - "Not enough information for discovery " + uri, - e); + throw new IllegalArgumentException("Not enough information for discovery " + uri, e); } if (pools != null) { - Map.Entry> entry = pools - .entrySet().iterator().next(); - pool = entry.getKey(); + Map.Entry> entry = pools.entrySet().iterator() + .next(); details = entry.getValue(); break; } @@ -297,19 +280,17 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements parameters.setPort(0); parameters.setPath(hostPath); } else { - s_logger.warn("Unable to figure out the scheme for URI: " + uri); - throw new IllegalArgumentException( - "Unable to figure out the scheme for URI: " + uri); + s_logger.warn("Unable to figure out the scheme for URI: " + uri); + throw new IllegalArgumentException("Unable to figure out the scheme for URI: " + uri); } } if (localStorage == null) { - List pools = primaryDataStoreDao - .listPoolByHostPath(storageHost, hostPath); + List pools = primaryDataStoreDao.listPoolByHostPath(storageHost, hostPath); if (!pools.isEmpty() && !scheme.equalsIgnoreCase("sharedmountpoint")) { Long oldPodId = pools.get(0).getPodId(); - throw new CloudRuntimeException("Storage pool " + uri - + " already in use by another pod (id=" + oldPodId + ")"); + throw new CloudRuntimeException("Storage pool " + uri + " already in use by another pod (id=" + + oldPodId + ")"); } } @@ -317,29 +298,23 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements String uuid = null; if (existingUuid != null) { - uuid = (String)existingUuid; - } else if (scheme.equalsIgnoreCase("sharedmountpoint") - || scheme.equalsIgnoreCase("clvm")) { + uuid = (String) existingUuid; + } else if (scheme.equalsIgnoreCase("sharedmountpoint") || scheme.equalsIgnoreCase("clvm")) { uuid = UUID.randomUUID().toString(); } else if (scheme.equalsIgnoreCase("PreSetup")) { uuid = hostPath.replace("/", ""); } else { - uuid = UUID.nameUUIDFromBytes( - new String(storageHost + hostPath).getBytes()).toString(); + uuid = UUID.nameUUIDFromBytes(new String(storageHost + hostPath).getBytes()).toString(); } - - List spHandles = primaryDataStoreDao - .findIfDuplicatePoolsExistByUUID(uuid); + List spHandles = primaryDataStoreDao.findIfDuplicatePoolsExistByUUID(uuid); if ((spHandles != null) && (spHandles.size() > 0)) { if (s_logger.isDebugEnabled()) { s_logger.debug("Another active pool with the same uuid already exists"); } - throw new CloudRuntimeException( - "Another active pool with the same uuid already exists"); + throw new CloudRuntimeException("Another active pool with the same uuid already exists"); } - String poolName = (String) dsInfos.get("name"); parameters.setUuid(uuid); @@ -353,20 +328,13 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements } protected boolean createStoragePool(long hostId, StoragePool pool) { - s_logger.debug("creating pool " + pool.getName() + " on host " - + hostId); - if (pool.getPoolType() != StoragePoolType.NetworkFilesystem - && pool.getPoolType() != StoragePoolType.Filesystem - && pool.getPoolType() != StoragePoolType.IscsiLUN - && pool.getPoolType() != StoragePoolType.Iscsi - && pool.getPoolType() != StoragePoolType.VMFS - && pool.getPoolType() != StoragePoolType.SharedMountPoint - && pool.getPoolType() != StoragePoolType.PreSetup - && pool.getPoolType() != StoragePoolType.OCFS2 - && pool.getPoolType() != StoragePoolType.RBD - && pool.getPoolType() != StoragePoolType.CLVM) { - s_logger.warn(" Doesn't support storage pool type " - + pool.getPoolType()); + s_logger.debug("creating pool " + pool.getName() + " on host " + hostId); + if (pool.getPoolType() != StoragePoolType.NetworkFilesystem && pool.getPoolType() != StoragePoolType.Filesystem + && pool.getPoolType() != StoragePoolType.IscsiLUN && pool.getPoolType() != StoragePoolType.Iscsi + && pool.getPoolType() != StoragePoolType.VMFS && pool.getPoolType() != StoragePoolType.SharedMountPoint + && pool.getPoolType() != StoragePoolType.PreSetup && pool.getPoolType() != StoragePoolType.OCFS2 + && pool.getPoolType() != StoragePoolType.RBD && pool.getPoolType() != StoragePoolType.CLVM) { + s_logger.warn(" Doesn't support storage pool type " + pool.getPoolType()); return false; } CreateStoragePoolCommand cmd = new CreateStoragePoolCommand(true, pool); @@ -377,8 +345,7 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements primaryDataStoreDao.expunge(pool.getId()); String msg = ""; if (answer != null) { - msg = "Can not create storage pool through host " + hostId - + " due to " + answer.getDetails(); + msg = "Can not create storage pool through host " + hostId + " due to " + answer.getDetails(); s_logger.warn(msg); } else { msg = "Can not create storage pool through host " + hostId @@ -393,19 +360,15 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements public boolean attachCluster(DataStore store, ClusterScope scope) { PrimaryDataStoreInfo primarystore = (PrimaryDataStoreInfo) store; // Check if there is host up in this cluster - List allHosts = _resourceMgr.listAllUpAndEnabledHosts( - Host.Type.Routing, primarystore.getClusterId(), + List allHosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, primarystore.getClusterId(), primarystore.getPodId(), primarystore.getDataCenterId()); if (allHosts.isEmpty()) { - throw new CloudRuntimeException( - "No host up to associate a storage pool with in cluster " - + primarystore.getClusterId()); + throw new CloudRuntimeException("No host up to associate a storage pool with in cluster " + + primarystore.getClusterId()); } - if (primarystore.getPoolType() == StoragePoolType.OCFS2 - && !_ocfs2Mgr.prepareNodes(allHosts, primarystore)) { - s_logger.warn("Can not create storage pool " + primarystore - + " on cluster " + primarystore.getClusterId()); + if (primarystore.getPoolType() == StoragePoolType.OCFS2 && !_ocfs2Mgr.prepareNodes(allHosts, primarystore)) { + s_logger.warn("Can not create storage pool " + primarystore + " on cluster " + primarystore.getClusterId()); primaryDataStoreDao.expunge(primarystore.getId()); return false; } @@ -422,18 +385,16 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements List poolHosts = new ArrayList(); for (HostVO h : allHosts) { try { - this.storageMgr.connectHostToSharedPool(h.getId(), - primarystore.getId()); + this.storageMgr.connectHostToSharedPool(h.getId(), primarystore.getId()); poolHosts.add(h); } catch (Exception e) { - s_logger.warn("Unable to establish a connection between " + h - + " and " + primarystore, e); + s_logger.warn("Unable to establish a connection between " + h + " and " + primarystore, e); } } if (poolHosts.isEmpty()) { - s_logger.warn("No host can access storage pool " + primarystore - + " on cluster " + primarystore.getClusterId()); + s_logger.warn("No host can access storage pool " + primarystore + " on cluster " + + primarystore.getClusterId()); primaryDataStoreDao.expunge(primarystore.getId()); return false; } @@ -444,17 +405,16 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements @Override public boolean attachZone(DataStore dataStore, ZoneScope scope) { - List hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.KVM, scope.getScopeId()); - for (HostVO host : hosts) { - try { - this.storageMgr.connectHostToSharedPool(host.getId(), - dataStore.getId()); - } catch (Exception e) { - s_logger.warn("Unable to establish a connection between " + host - + " and " + dataStore, e); - } - } - this.dataStoreHelper.attachZone(dataStore); + List hosts = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByHypervisor(HypervisorType.KVM, + scope.getScopeId()); + for (HostVO host : hosts) { + try { + this.storageMgr.connectHostToSharedPool(host.getId(), dataStore.getId()); + } catch (Exception e) { + s_logger.warn("Unable to establish a connection between " + host + " and " + dataStore, e); + } + } + this.dataStoreHelper.attachZone(dataStore); return true; } @@ -487,16 +447,13 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements @DB @Override public boolean deleteDataStore(DataStore store) { - List hostPoolRecords = this._storagePoolHostDao - .listByPoolId(store.getId()); - StoragePool pool = (StoragePool)store; + List hostPoolRecords = this._storagePoolHostDao.listByPoolId(store.getId()); + StoragePool pool = (StoragePool) store; boolean deleteFlag = false; // Remove the SR associated with the Xenserver for (StoragePoolHostVO host : hostPoolRecords) { - DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand( - pool); - final Answer answer = agentMgr.easySend(host.getHostId(), - deleteCmd); + DeleteStoragePoolCommand deleteCmd = new DeleteStoragePoolCommand(pool); + final Answer answer = agentMgr.easySend(host.getHostId(), deleteCmd); if (answer != null && answer.getResult()) { deleteFlag = true; diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java index fed41da74fe..410416c4499 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/provider/CloudStackPrimaryDataStoreProviderImpl.java @@ -32,8 +32,7 @@ import org.apache.cloudstack.storage.datastore.lifecycle.CloudStackPrimaryDataSt import com.cloud.utils.component.ComponentContext; -public class CloudStackPrimaryDataStoreProviderImpl implements - PrimaryDataStoreProvider { +public class CloudStackPrimaryDataStoreProviderImpl implements PrimaryDataStoreProvider { private final String providerName = DataStoreProvider.DEFAULT_PRIMARY; protected PrimaryDataStoreDriver driver; @@ -74,7 +73,7 @@ public class CloudStackPrimaryDataStoreProviderImpl implements @Override public Set getTypes() { - Set types = new HashSet(); + Set types = new HashSet(); types.add(DataStoreProviderType.PRIMARY); return types; } diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index 31be988b086..ad506d1793c 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -35,7 +35,6 @@ import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.log4j.Logger; @@ -47,7 +46,6 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.storage.encoding.DecodedDataObject; import com.cloud.utils.storage.encoding.Decoder; - public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { private static final Logger s_logger = Logger.getLogger(SamplePrimaryDataStoreDriverImpl.class); @Inject @@ -56,6 +54,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver StoragePoolHostDao storeHostDao; @Inject DataObjectManager dataObjMgr; + public SamplePrimaryDataStoreDriverImpl() { } @@ -65,16 +64,15 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver return null; } - @Override public DataStoreTO getStoreTO(DataStore store) { // TODO Auto-generated method stub return null; } - private class CreateVolumeContext extends AsyncRpcConext { private final DataObject volume; + /** * @param callback */ @@ -89,33 +87,36 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver } - public Void createAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeContext context) { - /*CreateCmdResult result = null; - CreateObjectAnswer volAnswer = (CreateObjectAnswer) callback.getResult(); - if (volAnswer.getResult()) { - result = new CreateCmdResult(volAnswer.getPath(), volAnswer); - } else { - result = new CreateCmdResult("", null); - result.setResult(volAnswer.getDetails()); - } - - context.getParentCallback().complete(result);*/ + public Void createAsyncCallback(AsyncCallbackDispatcher callback, + CreateVolumeContext context) { + /* + * CreateCmdResult result = null; CreateObjectAnswer volAnswer = + * (CreateObjectAnswer) callback.getResult(); if (volAnswer.getResult()) + * { result = new CreateCmdResult(volAnswer.getPath(), volAnswer); } + * else { result = new CreateCmdResult("", null); + * result.setResult(volAnswer.getDetails()); } + * + * context.getParentCallback().complete(result); + */ return null; } @Override public void deleteAsync(DataObject vo, AsyncCompletionCallback callback) { - /*DeleteCommand cmd = new DeleteCommand(vo.getUri()); - - EndPoint ep = selector.select(vo); - AsyncRpcConext context = new AsyncRpcConext(callback); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().deleteCallback(null, null)) - .setContext(context); - ep.sendMessageAsync(cmd, caller);*/ + /* + * DeleteCommand cmd = new DeleteCommand(vo.getUri()); + * + * EndPoint ep = selector.select(vo); AsyncRpcConext + * context = new AsyncRpcConext(callback); + * AsyncCallbackDispatcher + * caller = AsyncCallbackDispatcher.create(this); + * caller.setCallback(caller.getTarget().deleteCallback(null, null)) + * .setContext(context); ep.sendMessageAsync(cmd, caller); + */ } - public Void deleteCallback(AsyncCallbackDispatcher callback, AsyncRpcConext context) { + public Void deleteCallback(AsyncCallbackDispatcher callback, + AsyncRpcConext context) { CommandResult result = new CommandResult(); Answer answer = callback.getResult(); if (!answer.getResult()) { @@ -124,83 +125,80 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver context.getParentCallback().complete(result); return null; } + /* - private class CreateVolumeFromBaseImageContext extends AsyncRpcConext { - private final VolumeObject volume; - - public CreateVolumeFromBaseImageContext(AsyncCompletionCallback callback, VolumeObject volume) { - super(callback); - this.volume = volume; - } - - public VolumeObject getVolume() { - return this.volume; - } - - } + * private class CreateVolumeFromBaseImageContext extends + * AsyncRpcConext { private final VolumeObject volume; + * + * public CreateVolumeFromBaseImageContext(AsyncCompletionCallback + * callback, VolumeObject volume) { super(callback); this.volume = volume; } + * + * public VolumeObject getVolume() { return this.volume; } + * + * } + * + * @Override public void createVolumeFromBaseImageAsync(VolumeObject volume, + * TemplateInfo template, AsyncCompletionCallback callback) { + * VolumeTO vol = this.dataStore.getVolumeTO(volume); List + * endPoints = this.dataStore.getEndPoints(); EndPoint ep = + * endPoints.get(0); String templateUri = + * template.getDataStore().grantAccess(template, ep); + * CreateVolumeFromBaseImageCommand cmd = new + * CreateVolumeFromBaseImageCommand(vol, templateUri); + * + * CreateVolumeFromBaseImageContext context = new + * CreateVolumeFromBaseImageContext(callback, volume); + * AsyncCallbackDispatcher caller + * = AsyncCallbackDispatcher.create(this); caller.setContext(context) + * .setCallback + * (caller.getTarget().createVolumeFromBaseImageAsyncCallback(null, null)); + * + * ep.sendMessageAsync(cmd, caller); } + */ + /* + * public Object + * createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher + * callback, + * CreateVolumeFromBaseImageContext context) { + * CreateVolumeAnswer answer = (CreateVolumeAnswer)callback.getResult(); + * CommandResult result = new CommandResult(); if (answer == null || + * answer.getDetails() != null) { result.setSuccess(false); if (answer != + * null) { result.setResult(answer.getDetails()); } } else { + * result.setSuccess(true); VolumeObject volume = context.getVolume(); + * volume.setPath(answer.getVolumeUuid()); } + * AsyncCompletionCallback parentCall = + * context.getParentCallback(); parentCall.complete(result); return null; } + */ @Override - public void createVolumeFromBaseImageAsync(VolumeObject volume, TemplateInfo template, AsyncCompletionCallback callback) { - VolumeTO vol = this.dataStore.getVolumeTO(volume); - List endPoints = this.dataStore.getEndPoints(); - EndPoint ep = endPoints.get(0); - String templateUri = template.getDataStore().grantAccess(template, ep); - CreateVolumeFromBaseImageCommand cmd = new CreateVolumeFromBaseImageCommand(vol, templateUri); - - CreateVolumeFromBaseImageContext context = new CreateVolumeFromBaseImageContext(callback, volume); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setContext(context) - .setCallback(caller.getTarget().createVolumeFromBaseImageAsyncCallback(null, null)); - - ep.sendMessageAsync(cmd, caller); - }*/ - /* - public Object createVolumeFromBaseImageAsyncCallback(AsyncCallbackDispatcher callback, CreateVolumeFromBaseImageContext context) { - CreateVolumeAnswer answer = (CreateVolumeAnswer)callback.getResult(); - CommandResult result = new CommandResult(); - if (answer == null || answer.getDetails() != null) { - result.setSuccess(false); - if (answer != null) { - result.setResult(answer.getDetails()); - } - } else { - result.setSuccess(true); - VolumeObject volume = context.getVolume(); - volume.setPath(answer.getVolumeUuid()); - } - AsyncCompletionCallback parentCall = context.getParentCallback(); - parentCall.complete(result); - return null; - }*/ - - @Override - public void createAsync(DataObject vol, - AsyncCompletionCallback callback) { + public void createAsync(DataObject vol, AsyncCompletionCallback callback) { EndPoint ep = selector.select(vol); CreateObjectCommand createCmd = new CreateObjectCommand(null); CreateVolumeContext context = new CreateVolumeContext(callback, vol); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setContext(context) - .setCallback(caller.getTarget().createAsyncCallback(null, null)); + caller.setContext(context).setCallback(caller.getTarget().createAsyncCallback(null, null)); ep.sendMessageAsync(createCmd, caller); } @Override public String grantAccess(DataObject object, EndPoint ep) { - //StoragePoolHostVO poolHost = storeHostDao.findByPoolHost(object.getDataStore().getId(), ep.getId()); + // StoragePoolHostVO poolHost = + // storeHostDao.findByPoolHost(object.getDataStore().getId(), + // ep.getId()); String uri = object.getUri(); try { DecodedDataObject obj = Decoder.decode(uri); if (obj.getPath() == null) { - //create an obj + // create an obj EndPoint newEp = selector.select(object); CreateObjectCommand createCmd = new CreateObjectCommand(null); - CreateObjectAnswer answer = (CreateObjectAnswer)ep.sendMessage(createCmd); + CreateObjectAnswer answer = (CreateObjectAnswer) ep.sendMessage(createCmd); if (answer.getResult()) { - //dataObjMgr.update(object, answer.getPath(), answer.getSize()); + // dataObjMgr.update(object, answer.getPath(), + // answer.getSize()); } else { s_logger.debug("failed to create object" + answer.getDetails()); throw new CloudRuntimeException("failed to create object" + answer.getDetails()); @@ -209,7 +207,7 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver return object.getUri(); } catch (URISyntaxException e) { - throw new CloudRuntimeException("uri parsed error", e); + throw new CloudRuntimeException("uri parsed error", e); } } @@ -226,14 +224,11 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver } @Override - public void revertSnapshot(SnapshotInfo snapshot, - AsyncCompletionCallback callback) { + public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { // TODO Auto-generated method stub } - - @Override public boolean canCopy(DataObject srcData, DataObject destData) { // TODO Auto-generated method stub @@ -241,24 +236,21 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver } @Override - public void copyAsync(DataObject srcdata, DataObject destData, - AsyncCompletionCallback callback) { + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { // TODO Auto-generated method stub } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } - @Override - public void takeSnapshot(SnapshotInfo snapshot, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } } diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java index ddd64e5ec98..504cb9a007f 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java @@ -54,18 +54,20 @@ public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLife PrimaryDataStoreHelper primaryStoreHelper; @Inject PrimaryDataStoreProviderManager providerMgr; + public SamplePrimaryDataStoreLifeCycleImpl() { } - + @Override public DataStore initialize(Map dsInfos) { - - DataStore store = primaryStoreHelper.createPrimaryDataStore(null); + + DataStore store = primaryStoreHelper.createPrimaryDataStore(null); return providerMgr.getPrimaryDataStore(store.getId()); } protected void attachCluster(DataStore store) { - //send down AttachPrimaryDataStoreCmd command to all the hosts in the cluster + // send down AttachPrimaryDataStoreCmd command to all the hosts in the + // cluster List endPoints = selector.selectAll(store); CreatePrimaryDataStoreCmd createCmd = new CreatePrimaryDataStoreCmd(store.getUri()); EndPoint ep = endPoints.get(0); @@ -73,14 +75,14 @@ public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLife if (host.getHypervisorType() == HypervisorType.XenServer) { ep.sendMessage(createCmd); } - + endPoints.get(0).sendMessage(createCmd); AttachPrimaryDataStoreCmd cmd = new AttachPrimaryDataStoreCmd(store.getUri()); for (EndPoint endp : endPoints) { endp.sendMessage(cmd); } } - + @Override public boolean attachCluster(DataStore dataStore, ClusterScope scope) { StoragePoolVO dataStoreVO = dataStoreDao.findById(dataStore.getId()); @@ -90,14 +92,13 @@ public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLife dataStoreVO.setStatus(StoragePoolStatus.Attaching); dataStoreVO.setScope(scope.getScopeType()); dataStoreDao.update(dataStoreVO.getId(), dataStoreVO); - - + attachCluster(dataStore); - + dataStoreVO = dataStoreDao.findById(dataStore.getId()); dataStoreVO.setStatus(StoragePoolStatus.Up); dataStoreDao.update(dataStoreVO.getId(), dataStoreVO); - + return true; } @@ -120,8 +121,7 @@ public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLife } @Override - public boolean attachHost(DataStore store, HostScope scope, - StoragePoolInfo existingInfo) { + public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { // TODO Auto-generated method stub return false; } diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java index 57424a7e0c3..87088214dbc 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java @@ -23,18 +23,15 @@ import java.util.Set; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreLifeCycle; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreProvider; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider.DataStoreProviderType; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.driver.SamplePrimaryDataStoreDriverImpl; import org.apache.cloudstack.storage.datastore.lifecycle.SamplePrimaryDataStoreLifeCycleImpl; import com.cloud.utils.component.ComponentContext; - public class SamplePrimaryDatastoreProviderImpl implements PrimaryDataStoreProvider { private final String providerName = "sample primary data store provider"; protected PrimaryDataStoreDriver driver; @@ -45,6 +42,7 @@ public class SamplePrimaryDatastoreProviderImpl implements PrimaryDataStoreProvi protected DataStoreLifeCycle lifecycle; protected String uuid; protected long id; + @Override public String getName() { return providerName; @@ -75,7 +73,7 @@ public class SamplePrimaryDatastoreProviderImpl implements PrimaryDataStoreProvi @Override public Set getTypes() { - Set types = new HashSet(); + Set types = new HashSet(); types.add(DataStoreProviderType.PRIMARY); return types; } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index eee9ba5e1d9..a296bab834a 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -44,7 +44,6 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { return null; } - @Override public DataStoreTO getStoreTO(DataStore store) { // TODO Auto-generated method stub @@ -93,19 +92,16 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { } - @Override - public void resize(DataObject data, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub - } + } - @Override - public void takeSnapshot(SnapshotInfo snapshot, - AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } + @Override + public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + } } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java index 39adf9f1075..03f241ef132 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java @@ -27,19 +27,17 @@ import org.springframework.stereotype.Component; @Component public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvider { - private final String name = "Solidfire Primary Data Store Provider"; + private final String name = "Solidfire Primary Data Store Provider"; + public SolidfirePrimaryDataStoreProvider() { - public SolidfirePrimaryDataStoreProvider() { + // TODO Auto-generated constructor stub + } - - // TODO Auto-generated constructor stub - } - - @Override - public String getName() { - return name; - } + @Override + public String getName() { + return name; + } @Override public DataStoreLifeCycle getDataStoreLifeCycle() { @@ -71,5 +69,4 @@ public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvid return null; } - } diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java index 63669c453d7..902f5953eb1 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/AopTestAdvice.java @@ -21,14 +21,14 @@ import org.aspectj.lang.ProceedingJoinPoint; import com.cloud.utils.db.Transaction; public class AopTestAdvice { - public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { - Transaction txn = Transaction.open(call.getSignature().getName()); - Object ret = null; - try { - ret = call.proceed(); - } finally { - txn.close(); - } - return ret; - } + public Object AopTestMethod(ProceedingJoinPoint call) throws Throwable { + Transaction txn = Transaction.open(call.getSignature().getName()); + Object ret = null; + try { + ret = call.proceed(); + } finally { + txn.close(); + } + return ret; + } } diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java index eb6fe453886..79215618914 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/ChildTestConfiguration.java @@ -24,28 +24,29 @@ import com.cloud.agent.AgentManager; import com.cloud.host.dao.HostDao; public class ChildTestConfiguration extends TestConfiguration { - - @Override - @Bean - public HostDao hostDao() { - HostDao dao = super.hostDao(); - HostDao nDao = Mockito.spy(dao); - return nDao; - } - - @Bean - public AgentManager agentMgr() { - return Mockito.mock(AgentManager.class); - } - - @Bean - public ImageMotionService imageMotion() { - return Mockito.mock(ImageMotionService.class); - } -/* @Override - @Bean - public PrimaryDataStoreDao primaryDataStoreDao() { - return Mockito.mock(PrimaryDataStoreDaoImpl.class); - }*/ + @Override + @Bean + public HostDao hostDao() { + HostDao dao = super.hostDao(); + HostDao nDao = Mockito.spy(dao); + return nDao; + } + + @Bean + public AgentManager agentMgr() { + return Mockito.mock(AgentManager.class); + } + + @Bean + public ImageMotionService imageMotion() { + return Mockito.mock(ImageMotionService.class); + } + + /* + * @Override + * + * @Bean public PrimaryDataStoreDao primaryDataStoreDao() { return + * Mockito.mock(PrimaryDataStoreDaoImpl.class); } + */ } diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java index 2c6092d7408..8e98771feab 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/TestConfiguration.java @@ -26,12 +26,13 @@ import com.cloud.host.dao.HostDaoImpl; @Configuration public class TestConfiguration { - @Bean - public HostDao hostDao() { - return new HostDaoImpl(); - } - @Bean - public PrimaryDataStoreDao primaryDataStoreDao() { - return new PrimaryDataStoreDaoImpl(); - } + @Bean + public HostDao hostDao() { + return new HostDaoImpl(); + } + + @Bean + public PrimaryDataStoreDao primaryDataStoreDao() { + return new PrimaryDataStoreDaoImpl(); + } } diff --git a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java index 5bc929d3efc..a745dafbc2f 100644 --- a/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/plugins/storage/volume/solidfire/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -25,11 +25,11 @@ import java.util.UUID; import javax.inject.Inject; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -import org.apache.cloudstack.storage.command.CreateObjectAnswer; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Matchers; import org.mockito.Mockito; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -42,8 +42,6 @@ import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; -import com.cloud.exception.AgentUnavailableException; -import com.cloud.exception.OperationTimedoutException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -52,88 +50,91 @@ import com.cloud.org.Cluster.ClusterType; import com.cloud.org.Managed.ManagedState; import com.cloud.resource.ResourceState; - @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations="classpath:/resource/storageContext.xml") +@ContextConfiguration(locations = "classpath:/resource/storageContext.xml") public class VolumeTest { - @Inject - HostDao hostDao; - @Inject - HostPodDao podDao; - @Inject - ClusterDao clusterDao; - @Inject - DataCenterDao dcDao; - @Inject - PrimaryDataStoreDao primaryStoreDao; - //@Inject - //PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; - @Inject - AgentManager agentMgr; - Long dcId; - Long clusterId; - @Before - public void setUp() { - //create data center - DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, "10.0.0.1/24", - null, null, NetworkType.Basic, null, null, true, true, null, null); - dc = dcDao.persist(dc); - dcId = dc.getId(); - //create pod + @Inject + HostDao hostDao; + @Inject + HostPodDao podDao; + @Inject + ClusterDao clusterDao; + @Inject + DataCenterDao dcDao; + @Inject + PrimaryDataStoreDao primaryStoreDao; + // @Inject + // PrimaryDataStoreProviderManager primaryDataStoreProviderMgr; + @Inject + AgentManager agentMgr; + Long dcId; + Long clusterId; - HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "192.168.56.1", "192.168.56.0/24", 8, "test"); - pod = podDao.persist(pod); - //create xen cluster - ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); - cluster.setHypervisorType(HypervisorType.XenServer.toString()); - cluster.setClusterType(ClusterType.CloudManaged); - cluster.setManagedState(ManagedState.Managed); - cluster = clusterDao.persist(cluster); - clusterId = cluster.getId(); - //create xen host + @Before + public void setUp() { + // create data center + DataCenterVO dc = new DataCenterVO(UUID.randomUUID().toString(), "test", "8.8.8.8", null, "10.0.0.1", null, + "10.0.0.1/24", null, null, NetworkType.Basic, null, null, true, true, null, null); + dc = dcDao.persist(dc); + dcId = dc.getId(); + // create pod - HostVO host = new HostVO(UUID.randomUUID().toString()); - host.setName("devcloud xen host"); - host.setType(Host.Type.Routing); - host.setPrivateIpAddress("192.168.56.2"); - host.setDataCenterId(dc.getId()); - host.setVersion("6.0.1"); - host.setAvailable(true); - host.setSetup(true); - host.setLastPinged(0); - host.setResourceState(ResourceState.Enabled); - host.setClusterId(cluster.getId()); + HostPodVO pod = new HostPodVO(UUID.randomUUID().toString(), dc.getId(), "192.168.56.1", "192.168.56.0/24", 8, + "test"); + pod = podDao.persist(pod); + // create xen cluster + ClusterVO cluster = new ClusterVO(dc.getId(), pod.getId(), "devcloud cluster"); + cluster.setHypervisorType(HypervisorType.XenServer.toString()); + cluster.setClusterType(ClusterType.CloudManaged); + cluster.setManagedState(ManagedState.Managed); + cluster = clusterDao.persist(cluster); + clusterId = cluster.getId(); + // create xen host - host = hostDao.persist(host); - List results = new ArrayList(); - results.add(host); - Mockito.when(hostDao.listAll()).thenReturn(results); - Mockito.when(hostDao.findHypervisorHostInCluster(Mockito.anyLong())).thenReturn(results); - //CreateObjectAnswer createVolumeFromImageAnswer = new CreateObjectAnswer(null,UUID.randomUUID().toString(), null); + HostVO host = new HostVO(UUID.randomUUID().toString()); + host.setName("devcloud xen host"); + host.setType(Host.Type.Routing); + host.setPrivateIpAddress("192.168.56.2"); + host.setDataCenterId(dc.getId()); + host.setVersion("6.0.1"); + host.setAvailable(true); + host.setSetup(true); + host.setLastPinged(0); + host.setResourceState(ResourceState.Enabled); + host.setClusterId(cluster.getId()); + host = hostDao.persist(host); + List results = new ArrayList(); + results.add(host); + Mockito.when(hostDao.listAll()).thenReturn(results); + Mockito.when(hostDao.findHypervisorHostInCluster(Matchers.anyLong())).thenReturn(results); + // CreateObjectAnswer createVolumeFromImageAnswer = new + // CreateObjectAnswer(null,UUID.randomUUID().toString(), null); + // Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); + } - //Mockito.when(primaryStoreDao.findById(Mockito.anyLong())).thenReturn(primaryStore); - } + private PrimaryDataStoreInfo createPrimaryDataStore() { + try { + // primaryDataStoreProviderMgr.configure("primary data store mgr", + // new HashMap()); + // PrimaryDataStoreProvider provider = + // primaryDataStoreProviderMgr.getDataStoreProvider("Solidfre Primary Data Store Provider"); + Map params = new HashMap(); + params.put("url", "nfs://test/test"); + params.put("dcId", dcId.toString()); + params.put("clusterId", clusterId.toString()); + params.put("name", "my primary data store"); + // PrimaryDataStoreInfo primaryDataStoreInfo = + // provider.registerDataStore(params); + return null; + } catch (Exception e) { + return null; + } + } - private PrimaryDataStoreInfo createPrimaryDataStore() { - try { - //primaryDataStoreProviderMgr.configure("primary data store mgr", new HashMap()); - //PrimaryDataStoreProvider provider = primaryDataStoreProviderMgr.getDataStoreProvider("Solidfre Primary Data Store Provider"); - Map params = new HashMap(); - params.put("url", "nfs://test/test"); - params.put("dcId", dcId.toString()); - params.put("clusterId", clusterId.toString()); - params.put("name", "my primary data store"); - //PrimaryDataStoreInfo primaryDataStoreInfo = provider.registerDataStore(params); - return null; - } catch (Exception e) { - return null; - } - } - - @Test - public void createPrimaryDataStoreTest() { - createPrimaryDataStore(); - } + @Test + public void createPrimaryDataStoreTest() { + createPrimaryDataStore(); + } } From efbf9c8635916601badfcfcc401aac4ac11f1dee Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 29 May 2013 22:16:58 -0700 Subject: [PATCH 268/303] Move ExtractVolumeCmd from ManagementServerImpl to VolumeManagerImpl, also add support for S3 for ExtractVolumeCmd. --- .../com/cloud/server/ManagementService.java | 16 +- .../com/cloud/storage/VolumeApiService.java | 23 +- .../command/user/volume/ExtractVolumeCmd.java | 12 +- .../storage/volume/VolumeServiceImpl.java | 63 ++++- .../cloud/server/ManagementServerImpl.java | 185 +------------ .../src/com/cloud/storage/VolumeManager.java | 8 +- .../com/cloud/storage/VolumeManagerImpl.java | 255 +++++++++++++++++- 7 files changed, 344 insertions(+), 218 deletions(-) diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java index 3ff78424e8a..8d00ef202fd 100755 --- a/api/src/com/cloud/server/ManagementService.java +++ b/api/src/com/cloud/server/ManagementService.java @@ -240,20 +240,6 @@ public interface ManagementService { Map listCapabilities(ListCapabilitiesCmd cmd); - /** - * Extracts the volume to a particular location. - * - * @param cmd - * the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume - * exists), - * id (the id of the volume) - * @throws URISyntaxException - * @throws InternalErrorException - * @throws PermissionDeniedException - * - */ - Long extractVolume(ExtractVolumeCmd cmd) throws URISyntaxException; - /** * return an array of available hypervisors * @@ -381,7 +367,7 @@ public interface ManagementService { * @return List of capacities */ List listTopConsumedResources(ListCapacityCmd cmd); - + List listDeploymentPlanners(); VirtualMachine upgradeSystemVM(ScaleSystemVMCmd cmd) throws ResourceUnavailableException, ManagementServerException, VirtualMachineMigrationException, ConcurrentOperationException; diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 31b5c9501b8..58bd0fd3bcd 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -18,9 +18,12 @@ */ package com.cloud.storage; +import java.net.URISyntaxException; + import org.apache.cloudstack.api.command.user.volume.*; import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InternalErrorException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.user.Account; @@ -36,7 +39,7 @@ public interface VolumeApiService { * @throws PermissionDeniedException */ Volume allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException; - + /** * Creates the volume based on the given criteria * @@ -50,7 +53,7 @@ public interface VolumeApiService { /** * Resizes the volume based on the given criteria - * + * * @param cmd * the API command wrapping the criteria * @return the volume object @@ -77,8 +80,22 @@ public interface VolumeApiService { Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account account) throws ResourceAllocationException; - + Snapshot allocSnapshot(Long volumeId, Long policyId) throws ResourceAllocationException; Volume updateVolume(UpdateVolumeCmd updateVolumeCmd); + + /** + * Extracts the volume to a particular location. + * + * @param cmd + * the command specifying url (where the volume needs to be extracted to), zoneId (zone where the volume + * exists), + * id (the id of the volume) + * @throws URISyntaxException + * @throws InternalErrorException + * @throws PermissionDeniedException + * + */ + Long extractVolume(ExtractVolumeCmd cmd); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java index b86155b2a6c..d2beefffda8 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java @@ -126,9 +126,9 @@ public class ExtractVolumeCmd extends BaseAsyncCmd { @Override public void execute(){ - try { + // try { UserContext.current().setEventDetails("Volume Id: "+getId()); - Long uploadId = _mgr.extractVolume(this); + Long uploadId = _volumeService.extractVolume(this); if (uploadId != null){ Upload uploadInfo = _entityMgr.findById(Upload.class, uploadId); ExtractResponse response = new ExtractResponse(); @@ -150,9 +150,9 @@ public class ExtractVolumeCmd extends BaseAsyncCmd { } else { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract volume"); } - } catch (URISyntaxException ex) { - s_logger.info(ex); - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage()); - } + // } catch (URISyntaxException ex) { + // s_logger.info(ex); + // throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage()); + // } } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 09752eca00a..51516830653 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -65,6 +65,7 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.Host; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.StoragePool; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; @@ -635,6 +636,62 @@ public class VolumeServiceImpl implements VolumeService { return null; } + + protected AsyncCallFuture copyVolumeFromPrimaryToImage(VolumeInfo srcVolume, DataStore destStore) { + AsyncCallFuture future = new AsyncCallFuture(); + VolumeApiResult res = new VolumeApiResult(srcVolume); + VolumeInfo destVolume = null; + try { + destVolume = (VolumeInfo)destStore.create(srcVolume); + destVolume.processEvent(Event.CreateOnlyRequested); + srcVolume.processEvent(Event.CopyingRequested); // this is just used for locking that src volume record in DB to avoid using lock + + CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, + destVolume, + destStore); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); + caller.setCallback(caller.getTarget().copyVolumeFromPrimaryToImageCallback(null, null)) + .setContext(context); + + motionSrv.copyAsync(srcVolume, destVolume, caller); + return future; + } catch (Exception e) { + s_logger.error("failed to copy volume to image store", e); + if (destVolume != null) { + destVolume.processEvent(Event.OperationFailed); + } + srcVolume.processEvent(Event.OperationFailed); // unlock source volume record + res.setResult(e.toString()); + future.complete(res); + return future; + } + } + + protected Void copyVolumeFromPrimaryToImageCallback(AsyncCallbackDispatcher callback, CopyVolumeContext context) { + VolumeInfo srcVolume = context.srcVolume; + VolumeInfo destVolume = context.destVolume; + CopyCommandResult result = callback.getResult(); + AsyncCallFuture future = context.future; + VolumeApiResult res = new VolumeApiResult(destVolume); + try { + if (res.isFailed()) { + destVolume.processEvent(Event.OperationFailed); + srcVolume.processEvent(Event.OperationFailed); + res.setResult(result.getResult()); + future.complete(res); + }else{ + srcVolume.processEvent(Event.OperationSuccessed); + destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); + future.complete(res); + } + } catch (Exception e) { + res.setResult(e.toString()); + future.complete(res); + } + return null; + } + + @Override public AsyncCallFuture copyVolume(VolumeInfo srcVolume, DataStore destStore) { @@ -642,6 +699,10 @@ public class VolumeServiceImpl implements VolumeService { return copyVolumeFromImageToPrimary(srcVolume, destStore); } + if (destStore.getRole() == DataStoreRole.Image) { + return copyVolumeFromPrimaryToImage(srcVolume, destStore); + } + AsyncCallFuture future = new AsyncCallFuture(); VolumeApiResult res = new VolumeApiResult(srcVolume); try { @@ -1056,7 +1117,7 @@ public class VolumeServiceImpl implements VolumeService { * for (Long uniqueName : volumeInfos.keySet()) { TemplateProp vInfo = * volumeInfos.get(uniqueName); * expungeVolumeAsync(volFactory.getVolume(vInfo.getId(), store)); - * + * * String description = "Deleted volume " + vInfo.getTemplateName() + * " on image store " + storeId; s_logger.info(description); } */ diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 95ef6f4ad8f..17444ebdb33 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -17,7 +17,6 @@ package com.cloud.server; import java.lang.reflect.Field; -import java.net.URISyntaxException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.ArrayList; @@ -46,7 +45,6 @@ import org.apache.cloudstack.api.ApiConstants; import com.cloud.event.ActionEventUtils; import org.apache.cloudstack.api.BaseUpdateTemplateOrIsoCmd; import org.apache.cloudstack.api.command.admin.region.*; -import org.apache.cloudstack.api.response.ExtractResponse; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; import org.apache.cloudstack.affinity.AffinityGroupProcessor; @@ -397,26 +395,20 @@ import org.apache.cloudstack.api.command.user.vpn.UpdateVpnCustomerGatewayCmd; import org.apache.cloudstack.api.command.user.zone.ListZonesByCmd; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; -import com.cloud.agent.api.storage.CopyVolumeAnswer; -import com.cloud.agent.api.storage.CopyVolumeCommand; -import com.cloud.agent.api.storage.CreateVolumeOVAAnswer; -import com.cloud.agent.api.storage.CreateVolumeOVACommand; import com.cloud.agent.manager.allocator.HostAllocator; import com.cloud.alert.Alert; import com.cloud.alert.AlertManager; import com.cloud.alert.AlertVO; import com.cloud.alert.dao.AlertDao; import com.cloud.api.ApiDBUtils; -import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; -import com.cloud.async.AsyncJobResult; -import com.cloud.async.AsyncJobVO; -import com.cloud.async.BaseAsyncJobExecutor; import com.cloud.capacity.Capacity; import com.cloud.capacity.CapacityVO; import com.cloud.capacity.dao.CapacityDao; @@ -489,12 +481,9 @@ import com.cloud.storage.GuestOS; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.GuestOSVO; import com.cloud.storage.GuestOsCategory; -import com.cloud.storage.Storage; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.StorageManager; import com.cloud.storage.StoragePool; -import com.cloud.storage.Upload; -import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeManager; @@ -558,7 +547,6 @@ import edu.emory.mathcs.backport.java.util.Collections; import org.apache.cloudstack.api.command.admin.region.AddRegionCmd; import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd; import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.api.command.admin.config.ListDeploymentPlannersCmd; @@ -687,6 +675,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe ConfigurationServer _configServer; @Inject UserVmManager _userVmMgr; + @Inject + VolumeDataFactory _volFactory; private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker")); private final ScheduledExecutorService _alertExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AlertChecker")); @@ -3275,173 +3265,6 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe return _guestOSDao.findById(guestOsId); } - @Override - @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) - public Long extractVolume(ExtractVolumeCmd cmd) throws URISyntaxException { - Long volumeId = cmd.getId(); - String url = cmd.getUrl(); - Long zoneId = cmd.getZoneId(); - AsyncJobVO job = null; // FIXME: cmd.getJob(); - String mode = cmd.getMode(); - Account account = UserContext.current().getCaller(); - - if (!_accountMgr.isRootAdmin(account.getType()) && ApiDBUtils.isExtractionDisabled()) { - throw new PermissionDeniedException("Extraction has been disabled by admin"); - } - - VolumeVO volume = _volumeDao.findById(volumeId); - if (volume == null) { - InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId"); - ex.addProxyObject(volume, volumeId, "volumeId"); - throw ex; - } - - // perform permission check - _accountMgr.checkAccess(account, null, true, volume); - - if (_dcDao.findById(zoneId) == null) { - throw new InvalidParameterValueException("Please specify a valid zone."); - } - if (volume.getPoolId() == null) { - throw new InvalidParameterValueException("The volume doesnt belong to a storage pool so cant extract it"); - } - // Extract activity only for detached volumes or for volumes whose - // instance is stopped - if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) { - s_logger.debug("Invalid state of the volume with ID: " + volumeId - + ". It should be either detached or the VM should be in stopped state."); - PermissionDeniedException ex = new PermissionDeniedException( - "Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state."); - ex.addProxyObject(volume, volumeId, "volumeId"); - throw ex; - } - - if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont - // have any - // template - // dependence. - - VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); - if (template != null) { // For ISO based volumes template = null and - // we allow extraction of all ISO based - // volumes - boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; - if (!isExtractable && account != null && account.getType() != Account.ACCOUNT_TYPE_ADMIN) { // Global - // admins are always allowed to extract - PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted"); - ex.addProxyObject(volume, volumeId, "volumeId"); - throw ex; - } - } - } - - Upload.Mode extractMode; - if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) { - throw new InvalidParameterValueException("Please specify a valid extract Mode "); - } else { - extractMode = mode.equals(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; - } - - long accountId = volume.getAccountId(); - StoragePool srcPool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); - DataStore secStore = this.dataStoreMgr.getImageStore(zoneId); - String secondaryStorageURL = secStore.getUri(); - - List extractURLList = _uploadDao.listByTypeUploadStatus(volumeId, Upload.Type.VOLUME, UploadVO.Status.DOWNLOAD_URL_CREATED); - - if (extractMode == Upload.Mode.HTTP_DOWNLOAD && extractURLList.size() > 0) { - return extractURLList.get(0).getId(); // If download url already Note: volss - // exists then return - } else { - UploadVO uploadJob = _uploadMonitor.createNewUploadEntry(secStore.getId(), volumeId, UploadVO.Status.COPY_IN_PROGRESS, Upload.Type.VOLUME, - url, extractMode); - s_logger.debug("Extract Mode - " + uploadJob.getMode()); - uploadJob = _uploadDao.createForUpdate(uploadJob.getId()); - - // Update the async Job - - ExtractResponse resultObj = new ExtractResponse(ApiDBUtils.findVolumeById(volumeId).getUuid(), - volume.getName(), ApiDBUtils.findAccountById(accountId).getUuid(), UploadVO.Status.COPY_IN_PROGRESS.toString(), - uploadJob.getUuid()); - resultObj.setResponseName(cmd.getCommandName()); - AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); - if (asyncExecutor != null) { - job = asyncExecutor.getJob(); - _asyncMgr.updateAsyncJobAttachment(job.getId(), Upload.Type.VOLUME.toString(), volumeId); - _asyncMgr.updateAsyncJobStatus(job.getId(), AsyncJobResult.STATUS_IN_PROGRESS, resultObj); - } - String value = _configs.get(Config.CopyVolumeWait.toString()); - int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - // Copy the volume from the source storage pool to secondary storage - CopyVolumeCommand cvCmd = new CopyVolumeCommand(volume.getId(), volume.getPath(), srcPool, secondaryStorageURL, true, copyvolumewait); - CopyVolumeAnswer cvAnswer = null; - try { - cvAnswer = (CopyVolumeAnswer) _storageMgr.sendToPool(srcPool, cvCmd); - } catch (StorageUnavailableException e) { - s_logger.debug("Storage unavailable"); - } - - // Check if you got a valid answer. - if (cvAnswer == null || !cvAnswer.getResult()) { - String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage."; - - // Update the async job. - resultObj.setResultString(errorString); - resultObj.setUploadStatus(UploadVO.Status.COPY_ERROR.toString()); - if (asyncExecutor != null) { - _asyncMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_FAILED, 0, resultObj); - } - - // Update the DB that volume couldn't be copied - uploadJob.setUploadState(UploadVO.Status.COPY_ERROR); - uploadJob.setErrorString(errorString); - uploadJob.setLastUpdated(new Date()); - _uploadDao.update(uploadJob.getId(), uploadJob); - - throw new CloudRuntimeException(errorString); - } - - String volumeLocalPath = "volumes/" + volume.getId() + "/" + cvAnswer.getVolumePath() + "." + volume.getFormat().toString().toLowerCase(); - //Fang: volss, handle the ova special case; - if (getFormatForPool(srcPool) == "ova") { - CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, cvAnswer.getVolumePath(), srcPool, copyvolumewait); - CreateVolumeOVAAnswer OVAanswer = null; - - try { - cvOVACmd.setContextParam("hypervisor", HypervisorType.VMware.toString()); - OVAanswer = (CreateVolumeOVAAnswer) _storageMgr.sendToPool(srcPool, cvOVACmd); //Fang: for extract volume, create the ova file here; - - } catch (StorageUnavailableException e) { - s_logger.debug("Storage unavailable"); - } - } - // Update the DB that volume is copied and volumePath - uploadJob.setUploadState(UploadVO.Status.COPY_COMPLETE); - uploadJob.setLastUpdated(new Date()); - uploadJob.setInstallPath(volumeLocalPath); - _uploadDao.update(uploadJob.getId(), uploadJob); - - // create a URL. - _uploadMonitor.createVolumeDownloadURL(volumeId, volumeLocalPath, Upload.Type.VOLUME, zoneId, uploadJob.getId(), volume.getFormat()); - return uploadJob.getId(); - } - } - - private String getFormatForPool(StoragePool pool) { - ClusterVO cluster = ApiDBUtils.findClusterById(pool.getClusterId()); - - if (cluster.getHypervisorType() == HypervisorType.XenServer) { - return "vhd"; - } else if (cluster.getHypervisorType() == HypervisorType.KVM) { - return "qcow2"; - } else if (cluster.getHypervisorType() == HypervisorType.VMware) { - return "ova"; - } else if (cluster.getHypervisorType() == HypervisorType.Ovm) { - return "raw"; - } else { - return null; - } - } @Override public InstanceGroupVO updateVmGroup(UpdateVMGroupCmd cmd) { diff --git a/server/src/com/cloud/storage/VolumeManager.java b/server/src/com/cloud/storage/VolumeManager.java index d198e5dd7df..65c56d56233 100644 --- a/server/src/com/cloud/storage/VolumeManager.java +++ b/server/src/com/cloud/storage/VolumeManager.java @@ -18,11 +18,13 @@ */ package com.cloud.storage; +import java.net.URISyntaxException; import java.util.Map; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; @@ -33,6 +35,8 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientStorageCapacityException; +import com.cloud.exception.InternalErrorException; +import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; @@ -71,7 +75,7 @@ public interface VolumeManager extends VolumeApiService { boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException; - + void destroyVolume(VolumeVO volume); DiskProfile allocateRawVolume(Type type, String name, DiskOfferingVO offering, Long size, VMInstanceVO vm, Account owner); @@ -105,4 +109,6 @@ public interface VolumeManager extends VolumeApiService { DiskProfile allocateTemplatedVolume(Type type, String name, DiskOfferingVO offering, VMTemplateVO template, VMInstanceVO vm, Account owner); + + } diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index 5b02a9d3841..fcd714de546 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -18,11 +18,6 @@ */ package com.cloud.storage; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -43,11 +38,15 @@ import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; +import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; + +import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.storage.dao.*; import org.apache.cloudstack.api.command.user.volume.*; +import org.apache.cloudstack.api.response.ExtractResponse; 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.DataStoreProviderManager; @@ -73,16 +72,23 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.commons.lang.StringUtils; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.CreateVolumeOVAAnswer; +import com.cloud.agent.api.storage.CreateVolumeOVACommand; +import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.S3TO; +import com.cloud.agent.api.to.SwiftTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; +import com.cloud.async.AsyncJobResult; import com.cloud.async.AsyncJobVO; import com.cloud.async.BaseAsyncJobExecutor; import com.cloud.capacity.CapacityManager; @@ -113,6 +119,7 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; +import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -127,13 +134,14 @@ import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Volume.Event; +import com.cloud.storage.Upload.Status; import com.cloud.storage.Volume.Type; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolWorkDao; +import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateS3Dao; @@ -145,6 +153,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotApiService; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; +import com.cloud.storage.upload.UploadMonitor; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; @@ -157,6 +166,7 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.EnumUtils; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; +import com.cloud.utils.S3Utils; import com.cloud.utils.UriUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; @@ -320,6 +330,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { SnapshotDataFactory snapshotFactory; @Inject SnapshotApiService snapshotMgr; + @Inject + UploadMonitor _uploadMonitor; + @Inject + UploadDao _uploadDao; + private int _copyvolumewait; @Inject protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; @@ -691,8 +706,8 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { s_logger.debug("create volume failed: " + result.getResult()); throw new CloudRuntimeException("create volume failed:" + result.getResult()); } - - + + UsageEventVO usageEvent = new UsageEventVO( EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), @@ -1356,7 +1371,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { } else { vol.setDeviceId(1l); } - + vol.setFormat(this.getSupportedImageFormatForCluster(vm.getHypervisorType())); vol = _volsDao.persist(vol); @@ -1444,7 +1459,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { private VolumeInfo copyVolume(StoragePoolVO rootDiskPool , VolumeInfo volume, VMInstanceVO vm, VMTemplateVO rootDiskTmplt, DataCenterVO dcVO, HostPodVO pod, DiskOfferingVO diskVO, ServiceOfferingVO svo, HypervisorType rootDiskHyperType) throws NoTransitionException { - + if (!volume .getFormat() .equals( @@ -1498,7 +1513,7 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { ResourceType.primary_storage, new Long(volume.getSize())); } } - + VolumeVO volVO = this._volsDao.findById(vol.getId()); volVO.setFormat(this.getSupportedImageFormatForCluster(rootDiskHyperType)); this._volsDao.update(volVO.getId(), volVO); @@ -2597,4 +2612,222 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { return snapshotMgr.allocSnapshot(volumeId, policyId); } + + @Override + @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) + public Long extractVolume(ExtractVolumeCmd cmd) { + Long volumeId = cmd.getId(); + String url = cmd.getUrl(); + Long zoneId = cmd.getZoneId(); + AsyncJobVO job = null; // FIXME: cmd.getJob(); + String mode = cmd.getMode(); + Account account = UserContext.current().getCaller(); + + if (!_accountMgr.isRootAdmin(account.getType()) && ApiDBUtils.isExtractionDisabled()) { + throw new PermissionDeniedException("Extraction has been disabled by admin"); + } + + VolumeVO volume = _volumeDao.findById(volumeId); + if (volume == null) { + InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find volume with specified volumeId"); + ex.addProxyObject(volume, volumeId, "volumeId"); + throw ex; + } + + // perform permission check + _accountMgr.checkAccess(account, null, true, volume); + + if (_dcDao.findById(zoneId) == null) { + throw new InvalidParameterValueException("Please specify a valid zone."); + } + if (volume.getPoolId() == null) { + throw new InvalidParameterValueException("The volume doesnt belong to a storage pool so cant extract it"); + } + // Extract activity only for detached volumes or for volumes whose + // instance is stopped + if (volume.getInstanceId() != null && ApiDBUtils.findVMInstanceById(volume.getInstanceId()).getState() != State.Stopped) { + s_logger.debug("Invalid state of the volume with ID: " + volumeId + + ". It should be either detached or the VM should be in stopped state."); + PermissionDeniedException ex = new PermissionDeniedException( + "Invalid state of the volume with specified ID. It should be either detached or the VM should be in stopped state."); + ex.addProxyObject(volume, volumeId, "volumeId"); + throw ex; + } + + if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont + // have any + // template + // dependence. + + VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); + if (template != null) { // For ISO based volumes template = null and + // we allow extraction of all ISO based + // volumes + boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; + if (!isExtractable && account != null && account.getType() != Account.ACCOUNT_TYPE_ADMIN) { // Global + // admins are always allowed to extract + PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted"); + ex.addProxyObject(volume, volumeId, "volumeId"); + throw ex; + } + } + } + + Upload.Mode extractMode; + if (mode == null || (!mode.equals(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equals(Upload.Mode.HTTP_DOWNLOAD.toString()))) { + throw new InvalidParameterValueException("Please specify a valid extract Mode "); + } else { + extractMode = mode.equals(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; + } + + long accountId = volume.getAccountId(); + StoragePool srcPool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); + DataStore secStore = this.dataStoreMgr.getImageStore(zoneId); + String secondaryStorageURL = secStore.getUri(); + + List extractURLList = _uploadDao.listByTypeUploadStatus(volumeId, Upload.Type.VOLUME, UploadVO.Status.DOWNLOAD_URL_CREATED); + + if (extractMode == Upload.Mode.HTTP_DOWNLOAD && extractURLList.size() > 0) { + return extractURLList.get(0).getId(); // If download url already + // Note: volss + // exists then return + } else { + UploadVO uploadJob = _uploadMonitor.createNewUploadEntry(secStore.getId(), volumeId, UploadVO.Status.COPY_IN_PROGRESS, + Upload.Type.VOLUME, url, extractMode); + s_logger.debug("Extract Mode - " + uploadJob.getMode()); + uploadJob = _uploadDao.createForUpdate(uploadJob.getId()); + + // Update the async Job + + ExtractResponse resultObj = new ExtractResponse(ApiDBUtils.findVolumeById(volumeId).getUuid(), volume.getName(), ApiDBUtils + .findAccountById(accountId).getUuid(), UploadVO.Status.COPY_IN_PROGRESS.toString(), uploadJob.getUuid()); + resultObj.setResponseName(cmd.getCommandName()); + AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); + if (asyncExecutor != null) { + job = asyncExecutor.getJob(); + _asyncMgr.updateAsyncJobAttachment(job.getId(), Upload.Type.VOLUME.toString(), volumeId); + _asyncMgr.updateAsyncJobStatus(job.getId(), AsyncJobResult.STATUS_IN_PROGRESS, resultObj); + } + //TODO: AncientDataMotionStrategy.copyObject should use different timeout parent for different objects + String value = this._configDao.getValue(Config.CopyVolumeWait.toString()); + int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); + // Copy volume from primary to secondary storage + VolumeInfo srcVol = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture cvAnswer = this.volService.copyVolume(srcVol, secStore); + // Check if you got a valid answer. + VolumeApiResult cvResult = null; + try { + cvResult = cvAnswer.get(); + } catch (InterruptedException e1) { + s_logger.debug("failed copy volume", e1); + throw new CloudRuntimeException("Failed to copy volume" , e1); + } catch (ExecutionException e1) { + s_logger.debug("failed copy volume", e1); + throw new CloudRuntimeException("Failed to copy volume" , e1); + } + if (cvResult == null || cvResult.isFailed()) { + String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage."; + + // Update the async job. + resultObj.setResultString(errorString); + resultObj.setUploadStatus(UploadVO.Status.COPY_ERROR.toString()); + if (asyncExecutor != null) { + _asyncMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_FAILED, 0, resultObj); + } + + // Update the DB that volume couldn't be copied + uploadJob.setUploadState(UploadVO.Status.COPY_ERROR); + uploadJob.setErrorString(errorString); + uploadJob.setLastUpdated(new Date()); + _uploadDao.update(uploadJob.getId(), uploadJob); + + throw new CloudRuntimeException(errorString); + } + + VolumeInfo vol = cvResult.getVolume(); + String volumeLocalPath = vol.getPath(); + String volumeName = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(volumeLocalPath, "/"), "."); + // volss, handle the ova special case; + if (getFormatForPool(srcPool) == "ova") { + //TODO: need to handle this for S3 as secondary storage + CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, volumeName, srcPool, + copyvolumewait); + CreateVolumeOVAAnswer OVAanswer = null; + + try { + cvOVACmd.setContextParam("hypervisor", HypervisorType.VMware.toString()); + OVAanswer = (CreateVolumeOVAAnswer) storageMgr.sendToPool(srcPool, cvOVACmd); // Fang: + // for + // extract + // volume, + // create + // the + // ova + // file + // here; + + } catch (StorageUnavailableException e) { + s_logger.debug("Storage unavailable"); + } + } + // Update the DB that volume is copied and volumePath + uploadJob.setUploadState(UploadVO.Status.COPY_COMPLETE); + uploadJob.setLastUpdated(new Date()); + uploadJob.setInstallPath(volumeLocalPath); + _uploadDao.update(uploadJob.getId(), uploadJob); + + DataStoreTO volStore = secStore.getTO(); + if (volStore instanceof SwiftTO) { + throw new UnsupportedServiceException("ExtractVolume is not yet supported for Swift image store provider"); + } + + if (volStore instanceof S3TO) { + // for S3, no need to do anything, just return volume url for + // extract template. but we need to set object acl as public_read to + // make the url accessible + S3TO s3 = (S3TO) volStore; + String key = vol.getPath(); + try { + S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); + } catch (Exception ex) { + s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); + throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); + } + // construct the url from s3 + StringBuffer s3url = new StringBuffer(); + s3url.append(s3.isHttps() ? "https://" : "http://"); + s3url.append(s3.getEndPoint()); + s3url.append("/"); + s3url.append(s3.getBucketName()); + s3url.append("/"); + s3url.append(key); + + UploadVO vo = _uploadDao.createForUpdate(); + vo.setLastUpdated(new Date()); + vo.setUploadUrl(s3url.toString()); + vo.setUploadState(Status.DOWNLOAD_URL_CREATED); + _uploadDao.update(uploadJob.getId(), vo); + } else { + // create a URL. + _uploadMonitor.createVolumeDownloadURL(volumeId, volumeLocalPath, Upload.Type.VOLUME, zoneId, uploadJob.getId(), volume.getFormat()); + } + return uploadJob.getId(); + } + } + + private String getFormatForPool(StoragePool pool) { + ClusterVO cluster = ApiDBUtils.findClusterById(pool.getClusterId()); + + if (cluster.getHypervisorType() == HypervisorType.XenServer) { + return "vhd"; + } else if (cluster.getHypervisorType() == HypervisorType.KVM) { + return "qcow2"; + } else if (cluster.getHypervisorType() == HypervisorType.VMware) { + return "ova"; + } else if (cluster.getHypervisorType() == HypervisorType.Ovm) { + return "raw"; + } else { + return null; + } + } } From d6c6634d97cb88bdda223cf1b8b7bbe581b71db5 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 30 May 2013 12:21:03 -0700 Subject: [PATCH 269/303] Fix MS start issue --- client/tomcatconf/applicationContext.xml.in | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 42e20551d5b..92fdf4f1ce3 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -752,7 +752,6 @@ - @@ -776,7 +775,6 @@ - From 614e08e19f4e59248e3b611f3dbc5c533357d3e3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 30 May 2013 14:19:59 -0700 Subject: [PATCH 270/303] Fix ExtractVolume bug for S3 as secondary storage. --- .../subsystem/api/storage/VolumeInfo.java | 7 ++ .../storage/volume/VolumeObject.java | 67 +++++++++++++++++++ .../storage/volume/VolumeServiceImpl.java | 15 +++-- 3 files changed, 82 insertions(+), 7 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index d0b9be99678..463c0ff3538 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -18,6 +18,7 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; +import com.cloud.agent.api.Answer; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Volume; @@ -33,4 +34,10 @@ public interface VolumeInfo extends DataObject, Volume { public Long getLastPoolId(); public String getAttachedVmName(); + + public void processEventOnly(ObjectInDataStoreStateMachine.Event event); + + public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer); + + public boolean stateTransit(Volume.Event event); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index bc14b6ac673..1e2f00044bb 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -126,6 +126,7 @@ public class VolumeObject implements VolumeInfo { return volumeVO.getId(); } + @Override public boolean stateTransit(Volume.Event event) { boolean result = false; try { @@ -236,6 +237,22 @@ public class VolumeObject implements VolumeInfo { } + @Override + public void processEventOnly(ObjectInDataStoreStateMachine.Event event) { + try { + objectInStoreMgr.update(this, event); + } catch (Exception e) { + s_logger.debug("Failed to update state", e); + throw new CloudRuntimeException("Failed to update state:" + e.toString()); + } finally { + // in case of OperationFailed, expunge the entry + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + objectInStoreMgr.delete(this); + } + } + } + + @Override public String getName() { return this.volumeVO.getName(); @@ -434,6 +451,56 @@ public class VolumeObject implements VolumeInfo { } + @Override + public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer) { + try { + if (this.dataStore.getRole() == DataStoreRole.Primary) { + if (answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer; + VolumeVO vol = this.volumeDao.findById(this.getId()); + VolumeObjectTO newVol = (VolumeObjectTO) cpyAnswer.getNewData(); + vol.setPath(newVol.getPath()); + vol.setSize(newVol.getSize()); + vol.setPoolId(this.getDataStore().getId()); + volumeDao.update(vol.getId(), vol); + } else if (answer instanceof CreateObjectAnswer) { + CreateObjectAnswer createAnswer = (CreateObjectAnswer) answer; + VolumeObjectTO newVol = (VolumeObjectTO) createAnswer.getData(); + VolumeVO vol = this.volumeDao.findById(this.getId()); + vol.setPath(newVol.getPath()); + vol.setSize(newVol.getSize()); + vol.setPoolId(this.getDataStore().getId()); + volumeDao.update(vol.getId(), vol); + } + } else { + // image store or imageCache store + if (answer instanceof DownloadAnswer) { + DownloadAnswer dwdAnswer = (DownloadAnswer) answer; + VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), + this.getId()); + volStore.setInstallPath(dwdAnswer.getInstallPath()); + volStore.setChecksum(dwdAnswer.getCheckSum()); + this.volumeStoreDao.update(volStore.getId(), volStore); + } else if (answer instanceof CopyCmdAnswer) { + CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer; + VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(), + this.getId()); + VolumeObjectTO newVol = (VolumeObjectTO) cpyAnswer.getNewData(); + volStore.setInstallPath(newVol.getPath()); + volStore.setSize(newVol.getSize()); + this.volumeStoreDao.update(volStore.getId(), volStore); + } + } + } catch (RuntimeException ex) { + if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { + objectInStoreMgr.delete(this); + } + throw ex; + } + this.processEventOnly(event); + + } + @Override public ImageFormat getFormat() { return this.volumeVO.getFormat(); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 51516830653..99aac17e3da 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -623,6 +623,7 @@ public class VolumeServiceImpl implements VolumeService { srcVolume.processEvent(Event.OperationFailed); res.setResult(result.getResult()); future.complete(res); + return null; } srcVolume.processEvent(Event.OperationSuccessed); @@ -643,8 +644,8 @@ public class VolumeServiceImpl implements VolumeService { VolumeInfo destVolume = null; try { destVolume = (VolumeInfo)destStore.create(srcVolume); - destVolume.processEvent(Event.CreateOnlyRequested); - srcVolume.processEvent(Event.CopyingRequested); // this is just used for locking that src volume record in DB to avoid using lock + srcVolume.processEvent(Event.MigrationRequested); // this is just used for locking that src volume record in DB to avoid using lock + destVolume.processEventOnly(Event.CreateOnlyRequested); CopyVolumeContext context = new CopyVolumeContext(null, future, srcVolume, destVolume, @@ -658,7 +659,7 @@ public class VolumeServiceImpl implements VolumeService { } catch (Exception e) { s_logger.error("failed to copy volume to image store", e); if (destVolume != null) { - destVolume.processEvent(Event.OperationFailed); + destVolume.getDataStore().delete(destVolume); } srcVolume.processEvent(Event.OperationFailed); // unlock source volume record res.setResult(e.toString()); @@ -675,13 +676,13 @@ public class VolumeServiceImpl implements VolumeService { VolumeApiResult res = new VolumeApiResult(destVolume); try { if (res.isFailed()) { - destVolume.processEvent(Event.OperationFailed); - srcVolume.processEvent(Event.OperationFailed); + srcVolume.processEvent(Event.OperationFailed); // back to Ready state in Volume table + destVolume.processEventOnly(Event.OperationFailed); res.setResult(result.getResult()); future.complete(res); }else{ - srcVolume.processEvent(Event.OperationSuccessed); - destVolume.processEvent(Event.OperationSuccessed, result.getAnswer()); + srcVolume.processEvent(Event.OperationSuccessed); // back to Ready state in Volume table + destVolume.processEventOnly(Event.OperationSuccessed, result.getAnswer()); future.complete(res); } } catch (Exception e) { From eb93efdaa4f076a349b72542a295dc6808a2ffbe Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 30 May 2013 14:51:03 -0700 Subject: [PATCH 271/303] Add convenient delete methods in DataObject to delete dangling data object. --- .../engine/subsystem/api/storage/DataObject.java | 2 ++ .../storage/image/store/TemplateObject.java | 13 +++++++++++-- .../cloudstack/storage/snapshot/SnapshotObject.java | 7 +++++++ .../storage/datastore/PrimaryDataStoreImpl.java | 5 +++-- .../cloudstack/storage/volume/VolumeObject.java | 8 ++++++++ 5 files changed, 31 insertions(+), 4 deletions(-) diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index ef8798951c9..0cd21119a9b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -38,6 +38,8 @@ public interface DataObject { // public DiskFormat getFormat(); public String getUuid(); + boolean delete(); + public void processEvent(ObjectInDataStoreStateMachine.Event event); public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer); diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index e4be6277eac..9957791f061 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -125,12 +125,12 @@ public class TemplateObject implements TemplateInfo { } /* - * + * * // If the template that was passed into this allocator is not * installed in the storage pool, // add 3 * (template size on secondary * storage) to the running total VMTemplateHostVO templateHostVO = * _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), null); - * + * * if (templateHostVO == null) { VMTemplateSwiftVO templateSwiftVO = * _swiftMgr.findByTmpltId(templateForVmCreation.getId()); if * (templateSwiftVO != null) { long templateSize = @@ -395,4 +395,13 @@ public class TemplateObject implements TemplateInfo { return this.imageVO.getDomainId(); } + @Override + public boolean delete() { + if (dataStore != null) { + return dataStore.delete(this); + } + return true; + } + + } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 6aee3ea9503..bd145733afc 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -284,4 +284,11 @@ public class SnapshotObject implements SnapshotInfo { } + @Override + public boolean delete() { + if (store != null) { + return store.delete(this); + } + return true; + } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 6d380af668f..1fc82510b50 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -252,8 +252,9 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public boolean delete(DataObject obj) { - // TODO Auto-generated method stub - return false; + //TODO: clean up through driver + objectInStoreMgr.delete(obj); + return true; } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 1e2f00044bb..963015c7945 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -505,4 +505,12 @@ public class VolumeObject implements VolumeInfo { public ImageFormat getFormat() { return this.volumeVO.getFormat(); } + + @Override + public boolean delete() { + if (dataStore != null) { + return dataStore.delete(this); + } + return true; + } } From 2473ceb111804a2c9d5394919dac73e73669eb0c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 30 May 2013 17:39:44 -0700 Subject: [PATCH 272/303] Have different callback for create template and create volume since they will update different tables. --- .../CloudStackImageStoreDriverImpl.java | 50 +++++++++++++++++-- .../driver/S3ImageStoreDriverImpl.java | 47 +++++++++++++++-- .../driver/SwiftImageStoreDriverImpl.java | 49 ++++++++++++++++-- 3 files changed, 134 insertions(+), 12 deletions(-) diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 52595a1bc94..862af194df4 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -154,17 +154,16 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher .create(this); caller.setContext(context); - caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - if (data.getType() == DataObjectType.TEMPLATE) { + caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { + caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); _downloadMonitor.downloadVolumeToStorage(data, caller); } } - protected Void createAsyncCallback( - AsyncCallbackDispatcher callback, + protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, CreateContext context) { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; @@ -205,7 +204,48 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { templateDao.update(obj.getId(), templateDaoBuilder); } - CreateCmdResult result = new CreateCmdResult(null, answer); + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; + } + + protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); + if (volStoreVO != null) { + VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); + // update size in volume table + VolumeVO volUpdater = volumeDao.createForUpdate(); + volUpdater.setSize(answer.getTemplateSize()); + volumeDao.update(obj.getId(), volUpdater); + } + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSuccess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + CreateCmdResult result = new CreateCmdResult(null, null); caller.complete(result); } return null; diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 0a2a84064e7..6f500674c8a 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -173,11 +173,11 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { CreateContext context = new CreateContext(callback, data); AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); caller.setContext(context); - caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - if (data.getType() == DataObjectType.TEMPLATE) { + caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { + caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); _downloadMonitor.downloadVolumeToStorage(data, caller); } } @@ -214,7 +214,7 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } } - protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, CreateContext context) { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; @@ -261,6 +261,47 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { return null; } + protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); + if (volStoreVO != null) { + VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); + // update size in volume table + VolumeVO volUpdater = volumeDao.createForUpdate(); + volUpdater.setSize(answer.getTemplateSize()); + volumeDao.update(obj.getId(), volUpdater); + } + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSuccess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; + } + private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { TemplateObject templateObj = (TemplateObject) data; VMTemplateVO template = templateObj.getImage(); diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index 71b18d557cc..e5d40d12982 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -172,16 +172,16 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { AsyncCallbackDispatcher caller = AsyncCallbackDispatcher .create(this); caller.setContext(context); - caller.setCallback(caller.getTarget().createAsyncCallback(null, null)); - if (data.getType() == DataObjectType.TEMPLATE) { + caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); _downloadMonitor.downloadTemplateToStorage(data, caller); } else if (data.getType() == DataObjectType.VOLUME) { + caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); _downloadMonitor.downloadVolumeToStorage(data, caller); } } - protected Void createAsyncCallback(AsyncCallbackDispatcher callback, + protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, CreateContext context) { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; @@ -212,7 +212,7 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { CreateCmdResult result = new CreateCmdResult(null, null); - // result.setSucess(false); + result.setSuccess(false); result.setResult(answer.getErrorString()); caller.complete(result); } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { @@ -228,6 +228,47 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { return null; } + protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); + if (volStoreVO != null) { + VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); + // update size in volume table + VolumeVO volUpdater = volumeDao.createForUpdate(); + volUpdater.setSize(answer.getTemplateSize()); + volumeDao.update(obj.getId(), volUpdater); + } + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSuccess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; + } + private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { // TODO Auto-generated method stub VolumeVO vol = volumeDao.findById(data.getId()); From ef03d5a122ccce9ebd421f0060d5815ae532f3e2 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 4 Jun 2013 11:50:43 -0700 Subject: [PATCH 273/303] Move data store specific extract template/iso logic from TemplateManager to data store driver. --- .../cloud/template/TemplateApiService.java | 8 +- .../cloudstack/api/ResponseGenerator.java | 6 +- .../api/command/user/iso/ExtractIsoCmd.java | 13 +-- .../user/template/ExtractTemplateCmd.java | 13 +-- .../image/datastore/ImageStoreEntity.java | 3 + .../storage/image/store/ImageStoreImpl.java | 9 +- .../storage/image/ImageStoreDriver.java | 4 + .../CloudStackImageStoreDriverImpl.java | 46 ++++++++ .../driver/S3ImageStoreDriverImpl.java | 27 +++++ .../driver/SampleImageStoreDriverImpl.java | 9 ++ .../driver/SwiftImageStoreDriverImpl.java | 7 ++ .../src/com/cloud/api/ApiResponseHelper.java | 37 +++++-- .../cloud/template/TemplateManagerImpl.java | 100 ++---------------- .../storage/template/DownloadManagerImpl.java | 12 +-- 14 files changed, 156 insertions(+), 138 deletions(-) diff --git a/api/src/com/cloud/template/TemplateApiService.java b/api/src/com/cloud/template/TemplateApiService.java index d907b103ed4..26f381914c9 100755 --- a/api/src/com/cloud/template/TemplateApiService.java +++ b/api/src/com/cloud/template/TemplateApiService.java @@ -75,18 +75,18 @@ public interface TemplateApiService { * * @param cmd * - the command specifying the mode and id of the ISO - * @return extractId. + * @return extractUrl extract url. */ - Pair extract(ExtractIsoCmd cmd) throws InternalErrorException; + String extract(ExtractIsoCmd cmd) throws InternalErrorException; /** * Extracts a Template * * @param cmd * - the command specifying the mode and id of the template - * @return extractId + * @return extractUrl extract url */ - Pair extract(ExtractTemplateCmd cmd) throws InternalErrorException; + String extract(ExtractTemplateCmd cmd) throws InternalErrorException; VirtualMachineTemplate getTemplate(long templateId); diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 8cc9eaf785f..575a2ff97de 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -215,6 +215,8 @@ public interface ResponseGenerator { ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url); + ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url); + String toSerializedString(CreateCmdResponse response, String responseType); AsyncJobResponse createAsyncJobResponse(AsyncJob job); @@ -360,7 +362,7 @@ public interface ResponseGenerator { public NicResponse createNicResponse(Nic result); ApplicationLoadBalancerResponse createLoadBalancerContainerReponse(ApplicationLoadBalancerRule lb, Map lbInstances); - + AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group); Long getAffinityGroupId(String name, long entityOwnerId); @@ -370,7 +372,7 @@ public interface ResponseGenerator { PortableIpResponse createPortableIPResponse(PortableIp portableIp); InternalLoadBalancerElementResponse createInternalLbElementResponse(VirtualRouterProvider result); - + IsolationMethodResponse createIsolationMethodResponse(IsolationType method); } diff --git a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java index c405f2d6e91..dd0fc360e45 100644 --- a/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/iso/ExtractIsoCmd.java @@ -124,16 +124,9 @@ public class ExtractIsoCmd extends BaseAsyncCmd { public void execute(){ try { UserContext.current().setEventDetails(getEventDescription()); - Pair uploadPair = _templateService.extract(this); - if (uploadPair != null){ - ExtractResponse response = null; - if (uploadPair.second() != null ) { - // region-wide image store - response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second()); - } else { - // nfs image store - response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null); - } + String uploadUrl = _templateService.extract(this); + if (uploadUrl != null) { + ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl); response.setResponseName(getCommandName()); response.setObjectName("iso"); this.setResponseObject(response); diff --git a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java index 2ec957ebe86..f2dc5952386 100644 --- a/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/template/ExtractTemplateCmd.java @@ -126,16 +126,9 @@ public class ExtractTemplateCmd extends BaseAsyncCmd { public void execute(){ try { UserContext.current().setEventDetails(getEventDescription()); - Pair uploadPair = _templateService.extract(this); - if (uploadPair != null){ - ExtractResponse response = null; - if (uploadPair.second() != null ) { - // region-wide image store - response = _responseGenerator.createExtractResponse(null, id, zoneId, getEntityOwnerId(), mode, uploadPair.second()); - } else { - // nfs image store - response = _responseGenerator.createExtractResponse(uploadPair.first(), id, zoneId, getEntityOwnerId(), mode, null); - } + String uploadUrl = _templateService.extract(this); + if (uploadUrl != null) { + ExtractResponse response = _responseGenerator.createExtractResponse(id, zoneId, getEntityOwnerId(), mode, uploadUrl); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java index 636941c717f..90deff96c92 100644 --- a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java +++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java @@ -27,6 +27,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import com.cloud.storage.ImageStore; +import com.cloud.storage.Storage.ImageFormat; public interface ImageStoreEntity extends DataStore, ImageStore { TemplateInfo getTemplate(long templateId); @@ -40,4 +41,6 @@ public interface ImageStoreEntity extends DataStore, ImageStore { Set listTemplates(); String getMountPoint(); // get the mount point on ssvm. + + String createEntityExtractUrl(String installPath, ImageFormat format); // get the entity download URL } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index c6840d7aa17..a3da304bccc 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -42,6 +42,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.utils.component.ComponentContext; @@ -189,7 +190,13 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public String getMountPoint() { - return this.imageDataStoreVO.getParent(); + return imageDataStoreVO.getParent(); } + @Override + public String createEntityExtractUrl(String installPath, ImageFormat format) { + return driver.createEntityExtractUrl(this, installPath, format); + } + + } diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java index 712e1867523..85a42ff7c0c 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java @@ -18,7 +18,11 @@ */ package org.apache.cloudstack.storage.image; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; +import com.cloud.storage.Storage.ImageFormat; + public interface ImageStoreDriver extends DataStoreDriver { + String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format); } diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 862af194df4..243017fb58e 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -21,6 +21,7 @@ package org.apache.cloudstack.storage.datastore.driver; import java.util.Date; import java.util.List; import java.util.Set; +import java.util.UUID; import javax.inject.Inject; @@ -40,6 +41,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; @@ -48,6 +50,7 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand2; +import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.DownloadAnswer; @@ -55,12 +58,18 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; import com.cloud.host.dao.HostDao; import com.cloud.storage.DataStoreRole; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; +import com.cloud.storage.Upload.Mode; +import com.cloud.storage.Upload.Status; +import com.cloud.storage.Upload.Type; +import com.cloud.storage.UploadVO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateZoneVO; @@ -99,6 +108,8 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { @Inject AccountDao _accountDao; @Inject + ConfigurationDao _configDao; + @Inject SecondaryStorageVmManager _ssvmMgr; @Inject TemplateDataStoreDao _templateStoreDao; @@ -405,4 +416,39 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { } + @Override + public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { + // find an endpoint to send command + EndPoint ep = _epSelector.select(store); + // Create Symlink at ssvm + String path = installPath; + String uuid = UUID.randomUUID().toString() + "." + format.getFileExtension(); + CreateEntityDownloadURLCommand cmd = new CreateEntityDownloadURLCommand(((ImageStoreEntity) store).getMountPoint(), path, uuid); + Answer ans = ep.sendMessage(cmd); + if (ans == null || !ans.getResult()) { + String errorString = "Unable to create a link for entity at " + installPath + " on ssvm," + ans.getDetails(); + s_logger.error(errorString); + throw new CloudRuntimeException(errorString); + } + // Construct actual URL locally now that the symlink exists at SSVM + return generateCopyUrl(ep.getPublicAddr(), uuid); + } + + private String generateCopyUrl(String ipAddress, String uuid){ + + String hostname = ipAddress; + String scheme = "http"; + boolean _sslCopy = false; + String sslCfg = _configDao.getValue(Config.SecStorageEncryptCopy.toString()); + if ( sslCfg != null ){ + _sslCopy = Boolean.parseBoolean(sslCfg); + } + if (_sslCopy) { + hostname = ipAddress.replace(".", "-"); + hostname = hostname + ".realhostip.com"; + scheme = "https"; + } + return scheme + "://" + hostname + "/userdata/" + uuid; + } + } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 6f500674c8a..8cf4835dd53 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -48,6 +48,7 @@ import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.log4j.Logger; +import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand2; @@ -78,6 +79,7 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.user.Account; import com.cloud.user.dao.AccountDao; +import com.cloud.utils.S3Utils; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.dao.UserVmDao; @@ -422,4 +424,29 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } + @Override + public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { + // for S3, no need to do anything, just return template url for + // extract template. but we need to set object acl as public_read to + // make the url accessible + S3TO s3 = (S3TO)getStoreTO(store); + String key = installPath; + try { + S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); + } catch (Exception ex) { + s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); + throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); + } + // construct the url from s3 + StringBuffer s3url = new StringBuffer(); + s3url.append(s3.isHttps() ? "https://" : "http://"); + s3url.append(s3.getEndPoint()); + s3url.append("/"); + s3url.append(s3.getBucketName()); + s3url.append("/"); + s3url.append(key); + return s3url.toString(); + } + + } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index 27e60816155..abc8741ac5a 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -37,6 +37,7 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.dao.VMTemplateDao; //http-read-only based image store @@ -134,4 +135,12 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { // TODO Auto-generated method stub } + + @Override + public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { + // TODO Auto-generated method stub + return null; + } + + } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index e5d40d12982..bd48c446d08 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -61,6 +61,7 @@ import com.cloud.agent.api.to.SwiftTO; import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventUtils; +import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.dao.HostDao; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.DataStoreRole; @@ -424,4 +425,10 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } + @Override + public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { + throw new UnsupportedServiceException("Extract entity url is not yet supported for Swift image store provider"); + } + + } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 1cb425a1e68..310b3530327 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -16,9 +16,6 @@ // under the License. package com.cloud.api; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; - import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Calendar; @@ -40,7 +37,6 @@ import org.apache.cloudstack.affinity.AffinityGroup; import org.apache.cloudstack.affinity.AffinityGroupResponse; import org.apache.cloudstack.api.ApiConstants.HostDetails; import org.apache.cloudstack.api.ApiConstants.VMDetails; -import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.ResponseGenerator; import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd; import org.apache.cloudstack.api.response.AccountResponse; @@ -184,7 +180,6 @@ import com.cloud.configuration.ResourceLimit; import com.cloud.dao.EntityManager; import com.cloud.dc.ClusterVO; import com.cloud.dc.DataCenter; -import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.Pod; import com.cloud.dc.StorageNetworkIpRange; @@ -266,16 +261,10 @@ import com.cloud.storage.S3; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Upload; -import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.StoragePool; import com.cloud.storage.Swift; import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateHostVO; -import com.cloud.storage.VMTemplateS3VO; -import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateSwiftVO; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; @@ -1601,6 +1590,29 @@ public class ApiResponseHelper implements ResponseGenerator { return listSgs.get(0); } + //TODO: we need to deprecate uploadVO, since extract is done in a synchronous fashion + @Override + public ExtractResponse createExtractResponse(Long id, Long zoneId, Long accountId, String mode, String url) { + + ExtractResponse response = new ExtractResponse(); + response.setObjectName("template"); + VMTemplateVO template = ApiDBUtils.findTemplateById(id); + response.setId(template.getUuid()); + response.setName(template.getName()); + if (zoneId != null) { + DataCenter zone = ApiDBUtils.findZoneById(zoneId); + response.setZoneId(zone.getUuid()); + response.setZoneName(zone.getName()); + } + response.setMode(mode); + response.setUrl(url); + response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString()); + Account account = ApiDBUtils.findAccountById(accountId); + response.setAccountId(account.getUuid()); + + return response; + } + @Override public ExtractResponse createExtractResponse(Long uploadId, Long id, Long zoneId, Long accountId, String mode, String url) { @@ -3480,6 +3492,7 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } + @Override public NicSecondaryIpResponse createSecondaryIPToNicResponse(NicSecondaryIp result) { NicSecondaryIpResponse response = new NicSecondaryIpResponse(); NicVO nic = _entityMgr.findById(NicVO.class, result.getNicId()); @@ -3492,6 +3505,7 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } + @Override public NicResponse createNicResponse(Nic result) { NicResponse response = new NicResponse(); NetworkVO network = _entityMgr.findById(NetworkVO.class, result.getNetworkId()); @@ -3713,6 +3727,7 @@ public class ApiResponseHelper implements ResponseGenerator { } + @Override public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) { NetworkACLResponse response = new NetworkACLResponse(); response.setId(networkACL.getUuid()); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 94193d5c5a3..b39936f4ffc 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -384,7 +384,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, @Override @ActionEvent(eventType = EventTypes.EVENT_ISO_EXTRACT, eventDescription = "extracting ISO", async = true) - public Pair extract(ExtractIsoCmd cmd) { + public String extract(ExtractIsoCmd cmd) { Account account = UserContext.current().getCaller(); Long templateId = cmd.getId(); Long zoneId = cmd.getZoneId(); @@ -392,18 +392,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, String mode = cmd.getMode(); Long eventId = cmd.getStartEventId(); - // FIXME: async job needs fixing - Pair uploadPair = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr); - if (uploadPair != null) { - return uploadPair; - } else { - throw new CloudRuntimeException("Failed to extract the iso"); - } + return extract(account, templateId, url, zoneId, mode, eventId, true); } @Override @ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_EXTRACT, eventDescription = "extracting template", async = true) - public Pair extract(ExtractTemplateCmd cmd) { + public String extract(ExtractTemplateCmd cmd) { Account caller = UserContext.current().getCaller(); Long templateId = cmd.getId(); Long zoneId = cmd.getZoneId(); @@ -418,13 +412,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareExtractTemplate(cmd); - // FIXME: async job needs fixing - Pair uploadPair = extract(caller, templateId, url, zoneId, mode, eventId, false, null, _asyncMgr); - if (uploadPair != null) { - return uploadPair; - } else { - throw new CloudRuntimeException("Failed to extract the teamplate"); - } + return extract(caller, templateId, url, zoneId, mode, eventId, false); } @Override @@ -440,8 +428,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, return vmTemplate; } - private Pair extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO, - AsyncJobVO job, AsyncJobManager mgr) { + private String extract(Account caller, Long templateId, String url, Long zoneId, String mode, Long eventId, boolean isISO) { String desc = Upload.Type.TEMPLATE.toString(); if (isISO) { desc = Upload.Type.ISO.toString(); @@ -505,82 +492,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, throw new InvalidParameterValueException("The " + desc + " has not been downloaded "); } - if (tmpltStore.getProviderName().equalsIgnoreCase("Swift")) { - throw new UnsupportedServiceException("ExtractTemplate is not yet supported for Swift image store provider"); - } - - if (tmpltStore.getProviderName().equalsIgnoreCase("S3")) { - // for S3, no need to do anything, just return template url for - // extract template. but we need to set object acl as public_read to - // make the url accessible - S3TO s3 = (S3TO) tmpltStore.getTO(); - String key = tmpltStoreRef.getLocalDownloadPath(); - try { - S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); - } catch (Exception ex) { - s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); - throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); - } - // construct the url from s3 - StringBuffer s3url = new StringBuffer(); - s3url.append(s3.isHttps() ? "https://" : "http://"); - s3url.append(s3.getEndPoint()); - s3url.append("/"); - s3url.append(s3.getBucketName()); - s3url.append("/"); - s3url.append(key); - - return new Pair(null, s3url.toString()); - } - - // for NFS image store case, control will come here - Upload.Mode extractMode; - if (mode == null - || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString()))) { - throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: " + Upload.Mode.FTP_UPLOAD + ", " - + Upload.Mode.HTTP_DOWNLOAD); - } else { - extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; - } - - if (extractMode == Upload.Mode.FTP_UPLOAD) { - URI uri = null; - try { - uri = new URI(url); - if ((uri.getScheme() == null) || (!uri.getScheme().equalsIgnoreCase("ftp"))) { - throw new InvalidParameterValueException("Unsupported scheme for url: " + url); - } - } catch (Exception ex) { - throw new InvalidParameterValueException("Invalid url given: " + url); - } - - String host = uri.getHost(); - try { - InetAddress hostAddr = InetAddress.getByName(host); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLinkLocalAddress() || hostAddr.isLoopbackAddress() || hostAddr.isMulticastAddress()) { - throw new InvalidParameterValueException("Illegal host specified in url"); - } - if (hostAddr instanceof Inet6Address) { - throw new InvalidParameterValueException("IPV6 addresses not supported (" + hostAddr.getHostAddress() + ")"); - } - } catch (UnknownHostException uhe) { - throw new InvalidParameterValueException("Unable to resolve " + host); - } - - if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE)) { - throw new IllegalArgumentException(template.getName() - + " upload is in progress. Please wait for some time to schedule another upload for the same"); - } - - return new Pair(_uploadMonitor.extractTemplate(template, url, tmpltStoreRef, zoneId, eventId, job.getId(), mgr), null); - } - - UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltStoreRef, zoneId, eventId); - if (vo != null) { - return new Pair(vo.getId(), null); - } else { - return null; - } + return tmpltStore.createEntityExtractUrl(tmpltStoreRef.getInstallPath(), template.getFormat()); } public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index 81ddd673d20..bf68b299c5c 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -305,12 +305,12 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager // status to trigger callback. td.setStatus(Status.POST_DOWNLOAD_FINISHED); // set template size for S3 - if (td instanceof S3TemplateDownloader){ - long size = ((S3TemplateDownloader)td).totalBytes; - DownloadJob dnld = jobs.get(jobId); - dnld.setTemplatesize(size); - dnld.setTemplatePhysicalSize(size); - } + S3TemplateDownloader std = (S3TemplateDownloader) td; + long size = std.totalBytes; + DownloadJob dnld = jobs.get(jobId); + dnld.setTemplatesize(size); + dnld.setTemplatePhysicalSize(size); + dnld.setTmpltPath(std.getDownloadLocalPath()); // update template path to include file name. } dj.cleanup(); break; From e92cd6d632ca355edbd22c86cdc9228be9abf8db Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 4 Jun 2013 13:54:14 -0700 Subject: [PATCH 274/303] Move data store specific extract volume logic from VolumeManager to data store driver. --- .../com/cloud/storage/VolumeApiService.java | 2 +- .../command/user/volume/ExtractVolumeCmd.java | 49 ++--- .../src/com/cloud/api/ApiResponseHelper.java | 4 +- .../src/com/cloud/storage/VolumeManager.java | 12 +- .../com/cloud/storage/VolumeManagerImpl.java | 194 +++++------------- 5 files changed, 79 insertions(+), 182 deletions(-) diff --git a/api/src/com/cloud/storage/VolumeApiService.java b/api/src/com/cloud/storage/VolumeApiService.java index 58bd0fd3bcd..95f962df374 100644 --- a/api/src/com/cloud/storage/VolumeApiService.java +++ b/api/src/com/cloud/storage/VolumeApiService.java @@ -97,5 +97,5 @@ public interface VolumeApiService { * @throws PermissionDeniedException * */ - Long extractVolume(ExtractVolumeCmd cmd); + String extractVolume(ExtractVolumeCmd cmd); } diff --git a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java index d2beefffda8..5fbe106b334 100644 --- a/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/volume/ExtractVolumeCmd.java @@ -126,33 +126,26 @@ public class ExtractVolumeCmd extends BaseAsyncCmd { @Override public void execute(){ - // try { - UserContext.current().setEventDetails("Volume Id: "+getId()); - Long uploadId = _volumeService.extractVolume(this); - if (uploadId != null){ - Upload uploadInfo = _entityMgr.findById(Upload.class, uploadId); - ExtractResponse response = new ExtractResponse(); - response.setResponseName(getCommandName()); - response.setObjectName("volume"); - Volume vol = _entityMgr.findById(Volume.class, id); - response.setId(vol.getUuid()); - response.setName(vol.getName()); - DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId); - response.setZoneId(zone.getUuid()); - response.setZoneName(zone.getName()); - response.setMode(mode); - response.setUploadId(uploadInfo.getUuid()); - response.setState(uploadInfo.getUploadState().toString()); - Account account = _entityMgr.findById(Account.class, getEntityOwnerId()); - response.setAccountId(account.getUuid()); - response.setUrl(uploadInfo.getUploadUrl()); - this.setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract volume"); - } - // } catch (URISyntaxException ex) { - // s_logger.info(ex); - // throw new ServerApiException(ApiErrorCode.PARAM_ERROR, ex.getMessage()); - // } + UserContext.current().setEventDetails("Volume Id: " + getId()); + String uploadUrl = _volumeService.extractVolume(this); + if (uploadUrl != null) { + ExtractResponse response = new ExtractResponse(); + response.setResponseName(getCommandName()); + response.setObjectName("volume"); + Volume vol = _entityMgr.findById(Volume.class, id); + response.setId(vol.getUuid()); + response.setName(vol.getName()); + DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId); + response.setZoneId(zone.getUuid()); + response.setZoneName(zone.getName()); + response.setMode(mode); + response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString()); + Account account = _entityMgr.findById(Account.class, getEntityOwnerId()); + response.setAccountId(account.getUuid()); + response.setUrl(uploadUrl); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to extract volume"); + } } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 310b3530327..cf11b41f7ab 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1605,8 +1605,8 @@ public class ApiResponseHelper implements ResponseGenerator { response.setZoneName(zone.getName()); } response.setMode(mode); - response.setUrl(url); - response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString()); + response.setUrl(url); + response.setState(Upload.Status.DOWNLOAD_URL_CREATED.toString()); Account account = ApiDBUtils.findAccountById(accountId); response.setAccountId(account.getUuid()); diff --git a/server/src/com/cloud/storage/VolumeManager.java b/server/src/com/cloud/storage/VolumeManager.java index 65c56d56233..5f533ca3c5b 100644 --- a/server/src/com/cloud/storage/VolumeManager.java +++ b/server/src/com/cloud/storage/VolumeManager.java @@ -18,13 +18,11 @@ */ package com.cloud.storage; -import java.net.URISyntaxException; import java.util.Map; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd; -import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd; import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; @@ -35,8 +33,6 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientStorageCapacityException; -import com.cloud.exception.InternalErrorException; -import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; import com.cloud.host.Host; @@ -54,6 +50,7 @@ public interface VolumeManager extends VolumeApiService { Long destPoolClusterId, HypervisorType dataDiskHyperType) throws ConcurrentOperationException; + @Override VolumeVO uploadVolume(UploadVolumeCmd cmd) throws ResourceAllocationException; @@ -65,28 +62,35 @@ public interface VolumeManager extends VolumeApiService { String getVmNameOnVolume(Volume volume); + @Override VolumeVO allocVolume(CreateVolumeCmd cmd) throws ResourceAllocationException; + @Override VolumeVO createVolume(CreateVolumeCmd cmd); + @Override VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationException; + @Override boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException; void destroyVolume(VolumeVO volume); DiskProfile allocateRawVolume(Type type, String name, DiskOfferingVO offering, Long size, VMInstanceVO vm, Account owner); + @Override Volume attachVolumeToVM(AttachVolumeCmd command); + @Override Volume detachVolumeFromVM(DetachVolumeCmd cmmd); void release(VirtualMachineProfile profile); void cleanupVolumes(long vmId) throws ConcurrentOperationException; + @Override Volume migrateVolume(MigrateVolumeCmd cmd); void migrateVolumes(T vm, VirtualMachineTO vmTo, Host srcHost, Host destHost, diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java index fcd714de546..5abd4323114 100644 --- a/server/src/com/cloud/storage/VolumeManagerImpl.java +++ b/server/src/com/cloud/storage/VolumeManagerImpl.java @@ -43,10 +43,8 @@ import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd; -import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.storage.dao.*; import org.apache.cloudstack.api.command.user.volume.*; -import org.apache.cloudstack.api.response.ExtractResponse; 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.DataStoreProviderManager; @@ -72,23 +70,20 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.commons.lang.StringUtils; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.CreateVolumeOVAAnswer; import com.cloud.agent.api.storage.CreateVolumeOVACommand; -import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DiskTO; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; -import com.cloud.async.AsyncJobResult; import com.cloud.async.AsyncJobVO; import com.cloud.async.BaseAsyncJobExecutor; import com.cloud.capacity.CapacityManager; @@ -119,7 +114,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceAllocationException; import com.cloud.exception.StorageUnavailableException; -import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -134,7 +128,6 @@ import com.cloud.server.ManagementServer; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Upload.Status; import com.cloud.storage.Volume.Type; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; @@ -166,7 +159,6 @@ import com.cloud.uservm.UserVm; import com.cloud.utils.EnumUtils; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; -import com.cloud.utils.S3Utils; import com.cloud.utils.UriUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; @@ -2615,11 +2607,9 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { @Override @ActionEvent(eventType = EventTypes.EVENT_VOLUME_EXTRACT, eventDescription = "extracting volume", async = true) - public Long extractVolume(ExtractVolumeCmd cmd) { + public String extractVolume(ExtractVolumeCmd cmd) { Long volumeId = cmd.getId(); - String url = cmd.getUrl(); Long zoneId = cmd.getZoneId(); - AsyncJobVO job = null; // FIXME: cmd.getJob(); String mode = cmd.getMode(); Account account = UserContext.current().getCaller(); @@ -2654,18 +2644,16 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { throw ex; } - if (volume.getVolumeType() != Volume.Type.DATADISK) { // Datadisk dont - // have any - // template - // dependence. + if (volume.getVolumeType() != Volume.Type.DATADISK) { + // Datadisk dont have any template dependence. VMTemplateVO template = ApiDBUtils.findTemplateById(volume.getTemplateId()); if (template != null) { // For ISO based volumes template = null and // we allow extraction of all ISO based // volumes boolean isExtractable = template.isExtractable() && template.getTemplateType() != Storage.TemplateType.SYSTEM; - if (!isExtractable && account != null && account.getType() != Account.ACCOUNT_TYPE_ADMIN) { // Global - // admins are always allowed to extract + if (!isExtractable && account != null && account.getType() != Account.ACCOUNT_TYPE_ADMIN) { + // Global admins are always allowed to extract PermissionDeniedException ex = new PermissionDeniedException("The volume with specified volumeId is not allowed to be extracted"); ex.addProxyObject(volume, volumeId, "volumeId"); throw ex; @@ -2680,139 +2668,51 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager { extractMode = mode.equals(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD; } - long accountId = volume.getAccountId(); + // Clean up code to remove all those previous uploadVO and uploadMonitor code. Previous code is trying to fake an async operation purely in + // db table with uploadVO and async_job entry, but internal implementation is actually synchronous. StoragePool srcPool = (StoragePool) this.dataStoreMgr.getPrimaryDataStore(volume.getPoolId()); - DataStore secStore = this.dataStoreMgr.getImageStore(zoneId); + ImageStoreEntity secStore = (ImageStoreEntity) this.dataStoreMgr.getImageStore(zoneId); String secondaryStorageURL = secStore.getUri(); - List extractURLList = _uploadDao.listByTypeUploadStatus(volumeId, Upload.Type.VOLUME, UploadVO.Status.DOWNLOAD_URL_CREATED); - - if (extractMode == Upload.Mode.HTTP_DOWNLOAD && extractURLList.size() > 0) { - return extractURLList.get(0).getId(); // If download url already - // Note: volss - // exists then return - } else { - UploadVO uploadJob = _uploadMonitor.createNewUploadEntry(secStore.getId(), volumeId, UploadVO.Status.COPY_IN_PROGRESS, - Upload.Type.VOLUME, url, extractMode); - s_logger.debug("Extract Mode - " + uploadJob.getMode()); - uploadJob = _uploadDao.createForUpdate(uploadJob.getId()); - - // Update the async Job - - ExtractResponse resultObj = new ExtractResponse(ApiDBUtils.findVolumeById(volumeId).getUuid(), volume.getName(), ApiDBUtils - .findAccountById(accountId).getUuid(), UploadVO.Status.COPY_IN_PROGRESS.toString(), uploadJob.getUuid()); - resultObj.setResponseName(cmd.getCommandName()); - AsyncJobExecutor asyncExecutor = BaseAsyncJobExecutor.getCurrentExecutor(); - if (asyncExecutor != null) { - job = asyncExecutor.getJob(); - _asyncMgr.updateAsyncJobAttachment(job.getId(), Upload.Type.VOLUME.toString(), volumeId); - _asyncMgr.updateAsyncJobStatus(job.getId(), AsyncJobResult.STATUS_IN_PROGRESS, resultObj); - } - //TODO: AncientDataMotionStrategy.copyObject should use different timeout parent for different objects - String value = this._configDao.getValue(Config.CopyVolumeWait.toString()); - int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); - // Copy volume from primary to secondary storage - VolumeInfo srcVol = this.volFactory.getVolume(volume.getId()); - AsyncCallFuture cvAnswer = this.volService.copyVolume(srcVol, secStore); - // Check if you got a valid answer. - VolumeApiResult cvResult = null; - try { - cvResult = cvAnswer.get(); - } catch (InterruptedException e1) { - s_logger.debug("failed copy volume", e1); - throw new CloudRuntimeException("Failed to copy volume" , e1); - } catch (ExecutionException e1) { - s_logger.debug("failed copy volume", e1); - throw new CloudRuntimeException("Failed to copy volume" , e1); - } - if (cvResult == null || cvResult.isFailed()) { - String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage."; - - // Update the async job. - resultObj.setResultString(errorString); - resultObj.setUploadStatus(UploadVO.Status.COPY_ERROR.toString()); - if (asyncExecutor != null) { - _asyncMgr.completeAsyncJob(job.getId(), AsyncJobResult.STATUS_FAILED, 0, resultObj); - } - - // Update the DB that volume couldn't be copied - uploadJob.setUploadState(UploadVO.Status.COPY_ERROR); - uploadJob.setErrorString(errorString); - uploadJob.setLastUpdated(new Date()); - _uploadDao.update(uploadJob.getId(), uploadJob); - - throw new CloudRuntimeException(errorString); - } - - VolumeInfo vol = cvResult.getVolume(); - String volumeLocalPath = vol.getPath(); - String volumeName = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(volumeLocalPath, "/"), "."); - // volss, handle the ova special case; - if (getFormatForPool(srcPool) == "ova") { - //TODO: need to handle this for S3 as secondary storage - CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, volumeName, srcPool, - copyvolumewait); - CreateVolumeOVAAnswer OVAanswer = null; - - try { - cvOVACmd.setContextParam("hypervisor", HypervisorType.VMware.toString()); - OVAanswer = (CreateVolumeOVAAnswer) storageMgr.sendToPool(srcPool, cvOVACmd); // Fang: - // for - // extract - // volume, - // create - // the - // ova - // file - // here; - - } catch (StorageUnavailableException e) { - s_logger.debug("Storage unavailable"); - } - } - // Update the DB that volume is copied and volumePath - uploadJob.setUploadState(UploadVO.Status.COPY_COMPLETE); - uploadJob.setLastUpdated(new Date()); - uploadJob.setInstallPath(volumeLocalPath); - _uploadDao.update(uploadJob.getId(), uploadJob); - - DataStoreTO volStore = secStore.getTO(); - if (volStore instanceof SwiftTO) { - throw new UnsupportedServiceException("ExtractVolume is not yet supported for Swift image store provider"); - } - - if (volStore instanceof S3TO) { - // for S3, no need to do anything, just return volume url for - // extract template. but we need to set object acl as public_read to - // make the url accessible - S3TO s3 = (S3TO) volStore; - String key = vol.getPath(); - try { - S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); - } catch (Exception ex) { - s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); - throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); - } - // construct the url from s3 - StringBuffer s3url = new StringBuffer(); - s3url.append(s3.isHttps() ? "https://" : "http://"); - s3url.append(s3.getEndPoint()); - s3url.append("/"); - s3url.append(s3.getBucketName()); - s3url.append("/"); - s3url.append(key); - - UploadVO vo = _uploadDao.createForUpdate(); - vo.setLastUpdated(new Date()); - vo.setUploadUrl(s3url.toString()); - vo.setUploadState(Status.DOWNLOAD_URL_CREATED); - _uploadDao.update(uploadJob.getId(), vo); - } else { - // create a URL. - _uploadMonitor.createVolumeDownloadURL(volumeId, volumeLocalPath, Upload.Type.VOLUME, zoneId, uploadJob.getId(), volume.getFormat()); - } - return uploadJob.getId(); + String value = this._configDao.getValue(Config.CopyVolumeWait.toString()); + int copyvolumewait = NumbersUtil.parseInt(value, Integer.parseInt(Config.CopyVolumeWait.getDefaultValue())); + // Copy volume from primary to secondary storage + VolumeInfo srcVol = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture cvAnswer = this.volService.copyVolume(srcVol, secStore); + // Check if you got a valid answer. + VolumeApiResult cvResult = null; + try { + cvResult = cvAnswer.get(); + } catch (InterruptedException e1) { + s_logger.debug("failed copy volume", e1); + throw new CloudRuntimeException("Failed to copy volume", e1); + } catch (ExecutionException e1) { + s_logger.debug("failed copy volume", e1); + throw new CloudRuntimeException("Failed to copy volume", e1); } + if (cvResult == null || cvResult.isFailed()) { + String errorString = "Failed to copy the volume from the source primary storage pool to secondary storage."; + throw new CloudRuntimeException(errorString); + } + + VolumeInfo vol = cvResult.getVolume(); + String volumeLocalPath = vol.getPath(); + String volumeName = StringUtils.substringBeforeLast(StringUtils.substringAfterLast(volumeLocalPath, "/"), "."); + // volss, handle the ova special case; + if (getFormatForPool(srcPool) == "ova") { + // TODO: need to handle this for S3 as secondary storage + CreateVolumeOVACommand cvOVACmd = new CreateVolumeOVACommand(secondaryStorageURL, volumeLocalPath, volumeName, srcPool, copyvolumewait); + CreateVolumeOVAAnswer OVAanswer = null; + + try { + cvOVACmd.setContextParam("hypervisor", HypervisorType.VMware.toString()); + // for extract volume, create the ova file here; + OVAanswer = (CreateVolumeOVAAnswer) storageMgr.sendToPool(srcPool, cvOVACmd); + } catch (StorageUnavailableException e) { + s_logger.debug("Storage unavailable"); + } + } + return secStore.createEntityExtractUrl(vol.getPath(), vol.getFormat()); } private String getFormatForPool(StoragePool pool) { From 4e404953ad72862d7054cdd03eb6bea95d5fc00c Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 5 Jun 2013 09:40:33 -0700 Subject: [PATCH 275/303] Support Multi part upload for S3 using TransferManager. --- .../template/S3TemplateDownloader.java | 551 +++++++++--------- utils/src/com/cloud/utils/S3Utils.java | 2 +- 2 files changed, 262 insertions(+), 291 deletions(-) diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index 5ca6d338f5e..ca0df5d515e 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -16,20 +16,12 @@ // under the License. package com.cloud.storage.template; - import static com.cloud.utils.StringUtils.join; import static java.util.Arrays.asList; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.MalformedURLException; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.UnknownHostException; import java.util.Date; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; @@ -51,12 +43,15 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.amazonaws.AmazonClientException; -import com.amazonaws.AmazonServiceException; +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.ProgressEvent; import com.amazonaws.services.s3.model.ProgressListener; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.StorageClass; +import com.amazonaws.services.s3.transfer.TransferManager; +import com.amazonaws.services.s3.transfer.Upload; import com.cloud.agent.api.storage.Proxy; import com.cloud.agent.api.to.S3TO; import com.cloud.utils.Pair; @@ -68,367 +63,343 @@ import com.cloud.utils.UriUtils; * */ public class S3TemplateDownloader implements TemplateDownloader { - public static final Logger s_logger = Logger.getLogger(S3TemplateDownloader.class.getName()); + public static final Logger s_logger = Logger.getLogger(S3TemplateDownloader.class.getName()); private static final MultiThreadedHttpConnectionManager s_httpClientManager = new MultiThreadedHttpConnectionManager(); - private String downloadUrl; - private String installPath; - private String s3Key; - private String fileName; - public TemplateDownloader.Status status= TemplateDownloader.Status.NOT_STARTED; - public String errorString = " "; - private long remoteSize = 0; - public long downloadTime = 0; - public long totalBytes; - private final HttpClient client; - private GetMethod request; - private boolean resume = false; - private DownloadCompleteCallback completionCallback; - S3TO s3; - boolean inited = true; + private String downloadUrl; + private String installPath; + private String s3Key; + private String fileName; + public TemplateDownloader.Status status = TemplateDownloader.Status.NOT_STARTED; + public String errorString = " "; + private long remoteSize = 0; + public long downloadTime = 0; + public long totalBytes; + private final HttpClient client; + private GetMethod request; + private boolean resume = false; + private DownloadCompleteCallback completionCallback; + private S3TO s3; + private boolean inited = true; - private long MAX_TEMPLATE_SIZE_IN_BYTES; - private ResourceType resourceType = ResourceType.TEMPLATE; - private final HttpMethodRetryHandler myretryhandler; + private long maxTemplateSizeInByte; + private ResourceType resourceType = ResourceType.TEMPLATE; + private final HttpMethodRetryHandler myretryhandler; + public S3TemplateDownloader(S3TO storageLayer, String downloadUrl, String installPath, + DownloadCompleteCallback callback, long maxTemplateSizeInBytes, String user, String password, Proxy proxy, + ResourceType resourceType) { + this.s3 = storageLayer; + this.downloadUrl = downloadUrl; + this.installPath = installPath; + this.status = TemplateDownloader.Status.NOT_STARTED; + this.resourceType = resourceType; + this.maxTemplateSizeInByte = maxTemplateSizeInBytes; + this.totalBytes = 0; + this.client = new HttpClient(s_httpClientManager); - public S3TemplateDownloader (S3TO storageLayer, String downloadUrl, String installPath, DownloadCompleteCallback callback, long maxTemplateSizeInBytes, String user, String password, Proxy proxy, ResourceType resourceType) { - this.s3 = storageLayer; - this.downloadUrl = downloadUrl; - this.installPath = installPath; - this.status = TemplateDownloader.Status.NOT_STARTED; - this.resourceType = resourceType; - this.MAX_TEMPLATE_SIZE_IN_BYTES = maxTemplateSizeInBytes; + myretryhandler = new HttpMethodRetryHandler() { + @Override + public boolean retryMethod(final HttpMethod method, final IOException exception, int executionCount) { + if (executionCount >= 2) { + // Do not retry if over max retry count + return false; + } + if (exception instanceof NoHttpResponseException) { + // Retry if the server dropped connection on us + return true; + } + if (!method.isRequestSent()) { + // Retry if the request has not been sent fully or + // if it's OK to retry methods that have been sent + return true; + } + // otherwise do not retry + return false; + } + }; - this.totalBytes = 0; - this.client = new HttpClient(s_httpClientManager); + try { + this.request = new GetMethod(downloadUrl); + this.request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler); + this.completionCallback = callback; - myretryhandler = new HttpMethodRetryHandler() { - @Override - public boolean retryMethod( - final HttpMethod method, - final IOException exception, - int executionCount) { - if (executionCount >= 2) { - // Do not retry if over max retry count - return false; - } - if (exception instanceof NoHttpResponseException) { - // Retry if the server dropped connection on us - return true; - } - if (!method.isRequestSent()) { - // Retry if the request has not been sent fully or - // if it's OK to retry methods that have been sent - return true; - } - // otherwise do not retry - return false; - } - }; - - try { - this.request = new GetMethod(downloadUrl); - this.request.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, myretryhandler); - this.completionCallback = callback; - - Pair hostAndPort = UriUtils.validateUrl(downloadUrl); + Pair hostAndPort = UriUtils.validateUrl(downloadUrl); this.fileName = StringUtils.substringAfterLast(downloadUrl, "/"); - if (proxy != null) { - client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); - if (proxy.getUserName() != null) { - Credentials proxyCreds = new UsernamePasswordCredentials(proxy.getUserName(), proxy.getPassword()); - client.getState().setProxyCredentials(AuthScope.ANY, proxyCreds); - } - } - if ((user != null) && (password != null)) { - client.getParams().setAuthenticationPreemptive(true); - Credentials defaultcreds = new UsernamePasswordCredentials(user, password); - client.getState().setCredentials(new AuthScope(hostAndPort.first(), hostAndPort.second(), AuthScope.ANY_REALM), defaultcreds); - s_logger.info("Added username=" + user + ", password=" + password + "for host " + hostAndPort.first() + ":" + hostAndPort.second()); - } else { - s_logger.info("No credentials configured for host=" + hostAndPort.first() + ":" + hostAndPort.second()); - } - } catch (IllegalArgumentException iae) { - errorString = iae.getMessage(); - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - inited = false; - } catch (Exception ex){ - errorString = "Unable to start download -- check url? "; - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - s_logger.warn("Exception in constructor -- " + ex.toString()); - } catch (Throwable th) { - s_logger.warn("throwable caught ", th); - } - } + if (proxy != null) { + client.getHostConfiguration().setProxy(proxy.getHost(), proxy.getPort()); + if (proxy.getUserName() != null) { + Credentials proxyCreds = new UsernamePasswordCredentials(proxy.getUserName(), proxy.getPassword()); + client.getState().setProxyCredentials(AuthScope.ANY, proxyCreds); + } + } + if ((user != null) && (password != null)) { + client.getParams().setAuthenticationPreemptive(true); + Credentials defaultcreds = new UsernamePasswordCredentials(user, password); + client.getState().setCredentials( + new AuthScope(hostAndPort.first(), hostAndPort.second(), AuthScope.ANY_REALM), defaultcreds); + s_logger.info("Added username=" + user + ", password=" + password + "for host " + hostAndPort.first() + + ":" + hostAndPort.second()); + } else { + s_logger.info("No credentials configured for host=" + hostAndPort.first() + ":" + hostAndPort.second()); + } + } catch (IllegalArgumentException iae) { + errorString = iae.getMessage(); + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + inited = false; + } catch (Exception ex) { + errorString = "Unable to start download -- check url? "; + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + s_logger.warn("Exception in constructor -- " + ex.toString()); + } catch (Throwable th) { + s_logger.warn("throwable caught ", th); + } + } + @Override + public long download(boolean resume, DownloadCompleteCallback callback) { + switch (status) { + case ABORTED: + case UNRECOVERABLE_ERROR: + case DOWNLOAD_FINISHED: + return 0; + default: - @Override - public long download(boolean resume, DownloadCompleteCallback callback) { - switch (status) { - case ABORTED: - case UNRECOVERABLE_ERROR: - case DOWNLOAD_FINISHED: - return 0; - default: + } - } - - - int bytes=0; - try { - // execute get method - int responseCode = HttpStatus.SC_OK; - if ((responseCode = client.executeMethod(request)) != HttpStatus.SC_OK) { - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - errorString = " HTTP Server returned " + responseCode + " (expected 200 OK) "; - return 0; //FIXME: retry? - } - // get the total size of file + try { + // execute get method + int responseCode = HttpStatus.SC_OK; + if ((responseCode = client.executeMethod(request)) != HttpStatus.SC_OK) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = " HTTP Server returned " + responseCode + " (expected 200 OK) "; + return 0; // FIXME: retry? + } + // get the total size of file Header contentLengthHeader = request.getResponseHeader("Content-Length"); boolean chunked = false; long remoteSize2 = 0; if (contentLengthHeader == null) { - Header chunkedHeader = request.getResponseHeader("Transfer-Encoding"); - if (chunkedHeader == null || !"chunked".equalsIgnoreCase(chunkedHeader.getValue())) { - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - errorString=" Failed to receive length of download "; - return 0; //FIXME: what status do we put here? Do we retry? - } else if ("chunked".equalsIgnoreCase(chunkedHeader.getValue())){ - chunked = true; - } + Header chunkedHeader = request.getResponseHeader("Transfer-Encoding"); + if (chunkedHeader == null || !"chunked".equalsIgnoreCase(chunkedHeader.getValue())) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = " Failed to receive length of download "; + return 0; // FIXME: what status do we put here? Do we retry? + } else if ("chunked".equalsIgnoreCase(chunkedHeader.getValue())) { + chunked = true; + } } else { - remoteSize2 = Long.parseLong(contentLengthHeader.getValue()); + remoteSize2 = Long.parseLong(contentLengthHeader.getValue()); } if (remoteSize == 0) { - remoteSize = remoteSize2; + remoteSize = remoteSize2; } - if (remoteSize > MAX_TEMPLATE_SIZE_IN_BYTES) { - s_logger.info("Remote size is too large: " + remoteSize + " , max=" + MAX_TEMPLATE_SIZE_IN_BYTES); - status = Status.UNRECOVERABLE_ERROR; - errorString = "Download file size is too large"; - return 0; + if (remoteSize > maxTemplateSizeInByte) { + s_logger.info("Remote size is too large: " + remoteSize + " , max=" + maxTemplateSizeInByte); + status = Status.UNRECOVERABLE_ERROR; + errorString = "Download file size is too large"; + return 0; } if (remoteSize == 0) { - remoteSize = MAX_TEMPLATE_SIZE_IN_BYTES; + remoteSize = maxTemplateSizeInByte; } - InputStream in = !chunked?new BufferedInputStream(request.getResponseBodyAsStream()) - : new ChunkedInputStream(request.getResponseBodyAsStream()); + InputStream in = !chunked ? new BufferedInputStream(request.getResponseBodyAsStream()) + : new ChunkedInputStream(request.getResponseBodyAsStream()); - s_logger.info("Starting download from " + getDownloadUrl() + " to s3 bucket " + s3.getBucketName() + " remoteSize=" + remoteSize + " , max size=" + MAX_TEMPLATE_SIZE_IN_BYTES); + s_logger.info("Starting download from " + getDownloadUrl() + " to s3 bucket " + s3.getBucketName() + + " remoteSize=" + remoteSize + " , max size=" + maxTemplateSizeInByte); Date start = new Date(); // compute s3 key s3Key = join(asList(installPath, fileName), S3Utils.SEPARATOR); + // multi-part upload using S3 api to handle > 5G input stream + TransferManager tm = new TransferManager(S3Utils.acquireClient(s3)); + // download using S3 API ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(remoteSize); - PutObjectRequest putObjectRequest = new PutObjectRequest( - s3.getBucketName(), s3Key, in, metadata) + PutObjectRequest putObjectRequest = new PutObjectRequest(s3.getBucketName(), s3Key, in, metadata) .withStorageClass(StorageClass.ReducedRedundancy); // register progress listenser - putObjectRequest - .setProgressListener(new ProgressListener() { - @Override - public void progressChanged( - ProgressEvent progressEvent) { - // s_logger.debug(progressEvent.getBytesTransfered() - // + " number of byte transferd " - // + new Date()); - totalBytes += progressEvent.getBytesTransfered(); - if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) { - s_logger.info("download completed"); - status = TemplateDownloader.Status.DOWNLOAD_FINISHED; - } else if (progressEvent.getEventCode() == ProgressEvent.FAILED_EVENT_CODE){ - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - } else if (progressEvent.getEventCode() == ProgressEvent.CANCELED_EVENT_CODE){ - status = TemplateDownloader.Status.ABORTED; - } else{ - status = TemplateDownloader.Status.IN_PROGRESS; - } - } + putObjectRequest.setProgressListener(new ProgressListener() { + @Override + public void progressChanged(ProgressEvent progressEvent) { + // s_logger.debug(progressEvent.getBytesTransfered() + // + " number of byte transferd " + // + new Date()); + totalBytes += progressEvent.getBytesTransfered(); + if (progressEvent.getEventCode() == ProgressEvent.COMPLETED_EVENT_CODE) { + s_logger.info("download completed"); + status = TemplateDownloader.Status.DOWNLOAD_FINISHED; + } else if (progressEvent.getEventCode() == ProgressEvent.FAILED_EVENT_CODE) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + } else if (progressEvent.getEventCode() == ProgressEvent.CANCELED_EVENT_CODE) { + status = TemplateDownloader.Status.ABORTED; + } else { + status = TemplateDownloader.Status.IN_PROGRESS; + } + } + + }); + // TransferManager processes all transfers asynchronously, + // so this call will return immediately. + Upload upload = tm.upload(putObjectRequest); + + upload.waitForCompletion(); - }); - S3Utils.putObject(s3, putObjectRequest); - while (status != TemplateDownloader.Status.DOWNLOAD_FINISHED && - status != TemplateDownloader.Status.UNRECOVERABLE_ERROR && - status != TemplateDownloader.Status.ABORTED ){ - // wait for completion - } // finished or aborted Date finish = new Date(); String downloaded = "(incomplete download)"; if (totalBytes >= remoteSize) { - status = TemplateDownloader.Status.DOWNLOAD_FINISHED; - downloaded = "(download complete remote=" + remoteSize + "bytes)"; + status = TemplateDownloader.Status.DOWNLOAD_FINISHED; + downloaded = "(download complete remote=" + remoteSize + "bytes)"; } else { errorString = "Downloaded " + totalBytes + " bytes " + downloaded; } downloadTime += finish.getTime() - start.getTime(); return totalBytes; - }catch (HttpException hte) { - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - errorString = hte.getMessage(); - } catch (IOException ioe) { - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; //probably a file write error? - errorString = ioe.getMessage(); - } catch (AmazonClientException ex) { - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; // S3 api exception + } catch (HttpException hte) { + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = hte.getMessage(); + } catch (IOException ioe) { + // probably a file write error + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = ioe.getMessage(); + } catch (AmazonClientException ex) { + // S3 api exception + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; errorString = ex.getMessage(); - } finally { - // close input stream - request.releaseConnection(); + } catch (InterruptedException e) { + // S3 upload api exception + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + errorString = e.getMessage(); + } finally { + // close input stream + request.releaseConnection(); if (callback != null) { - callback.downloadComplete(status); + callback.downloadComplete(status); } - } - return 0; - } + } + return 0; + } - public String getDownloadUrl() { - return downloadUrl; - } + public String getDownloadUrl() { + return downloadUrl; + } - - @Override + @Override public TemplateDownloader.Status getStatus() { - return status; - } + return status; + } - - @Override + @Override public long getDownloadTime() { - return downloadTime; - } + return downloadTime; + } - - @Override + @Override public long getDownloadedBytes() { - return totalBytes; - } + return totalBytes; + } - @Override - @SuppressWarnings("fallthrough") - public boolean stopDownload() { - switch (getStatus()) { - case IN_PROGRESS: - if (request != null) { - request.abort(); - } - status = TemplateDownloader.Status.ABORTED; - return true; - case UNKNOWN: - case NOT_STARTED: - case RECOVERABLE_ERROR: - case UNRECOVERABLE_ERROR: - case ABORTED: - status = TemplateDownloader.Status.ABORTED; - case DOWNLOAD_FINISHED: + @Override + @SuppressWarnings("fallthrough") + public boolean stopDownload() { + switch (getStatus()) { + case IN_PROGRESS: + if (request != null) { + request.abort(); + } + status = TemplateDownloader.Status.ABORTED; + return true; + case UNKNOWN: + case NOT_STARTED: + case RECOVERABLE_ERROR: + case UNRECOVERABLE_ERROR: + case ABORTED: + status = TemplateDownloader.Status.ABORTED; + case DOWNLOAD_FINISHED: try { S3Utils.deleteObject(s3, s3.getBucketName(), s3Key); } catch (Exception ex) { // ignore delete exception if it is not there } - return true; + return true; - default: - return true; - } - } + default: + return true; + } + } - @Override - public int getDownloadPercent() { - if (remoteSize == 0) { - return 0; - } + @Override + public int getDownloadPercent() { + if (remoteSize == 0) { + return 0; + } - return (int)(100.0*totalBytes/remoteSize); - } + return (int) (100.0 * totalBytes / remoteSize); + } - @Override - public void run() { - try { - download(resume, completionCallback); - } catch (Throwable t) { - s_logger.warn("Caught exception during download "+ t.getMessage(), t); - errorString = "Failed to install: " + t.getMessage(); - status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; - } + @Override + public void run() { + try { + download(resume, completionCallback); + } catch (Throwable t) { + s_logger.warn("Caught exception during download " + t.getMessage(), t); + errorString = "Failed to install: " + t.getMessage(); + status = TemplateDownloader.Status.UNRECOVERABLE_ERROR; + } - } + } - @Override - public void setStatus(TemplateDownloader.Status status) { - this.status = status; - } + @Override + public void setStatus(TemplateDownloader.Status status) { + this.status = status; + } + public boolean isResume() { + return resume; + } + @Override + public String getDownloadError() { + return errorString; + } - public boolean isResume() { - return resume; - } + @Override + public String getDownloadLocalPath() { + return this.s3Key; + } - @Override - public String getDownloadError() { - return errorString; - } - - @Override - public String getDownloadLocalPath() { - return this.s3Key; - } - - @Override + @Override public void setResume(boolean resume) { - this.resume = resume; - } + this.resume = resume; + } - - @Override + @Override public long getMaxTemplateSizeInBytes() { - return this.MAX_TEMPLATE_SIZE_IN_BYTES; - } + return this.maxTemplateSizeInByte; + } - public static void main(String[] args) { - String url ="http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-noinstall-5.0.77-win32.zip/from/http://mirror.services.wisc.edu/mysql/"; - try { - URI uri = new java.net.URI(url); - } catch (URISyntaxException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - TemplateDownloader td = new S3TemplateDownloader(null, url,"/tmp/mysql", null, TemplateDownloader.DEFAULT_MAX_TEMPLATE_SIZE_IN_BYTES, null, null, null, null); - long bytes = td.download(true, null); - if (bytes > 0) { - System.out.println("Downloaded (" + bytes + " bytes)" + " in " + td.getDownloadTime()/1000 + " secs"); - } else { - System.out.println("Failed download"); - } + @Override + public void setDownloadError(String error) { + errorString = error; + } - } + @Override + public boolean isInited() { + return inited; + } - @Override - public void setDownloadError(String error) { - errorString = error; - } - - - - @Override - public boolean isInited() { - return inited; - } - - - public ResourceType getResourceType() { - return resourceType; - } + public ResourceType getResourceType() { + return resourceType; + } } diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index 711d1cb9fc4..f195215afb8 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -73,7 +73,7 @@ public final class S3Utils { super(); } - private static AmazonS3 acquireClient(final ClientOptions clientOptions) { + public static AmazonS3 acquireClient(final ClientOptions clientOptions) { final AWSCredentials credentials = new BasicAWSCredentials( clientOptions.getAccessKey(), clientOptions.getSecretKey()); From c78f3984fee809386a72674daf8930458e62807d Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 6 Jun 2013 14:06:10 -0700 Subject: [PATCH 276/303] Fix a bug in copyFromS3ToNfs code about path. --- .../resource/NfsSecondaryStorageResource.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index d6a2af4d5c7..228024e4edb 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -245,22 +245,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.debug("Directory " + downloadPath + " already exists"); } - List files = getDirectory(s3, s3.getBucketName(), destPath, downloadDirectory, new FileNamingStrategy() { + File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, new FileNamingStrategy() { @Override public String determineFileName(final String key) { return substringAfterLast(key, S3Utils.SEPARATOR); } }); - // find out template name - File destFile = null; - for (File f : files) { - if (!f.getName().endsWith(".properties")) { - destFile = f; - break; - } - } - if (destFile == null) { return new CopyCmdAnswer("Can't find template"); } @@ -335,6 +326,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } + protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { String srcMountPoint = this.getRootDir(srcDataStore.getUrl()); From 66e702222d2f0efab1db6ce0e895e5a21c3b7cd4 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 6 Jun 2013 18:00:38 -0700 Subject: [PATCH 277/303] Simplify various DeleteTemplateCommnad, DeleteVolumeCommand and DeleteSnapshotBackupCommand to use one DeleteCommand, also provide BaseImageStoreDriverImpl class for plugin to inherit to avoid code duplication. --- api/src/com/cloud/agent/api/to/DataTO.java | 2 + .../api/DeleteSnapshotBackupCommand2.java | 56 --- .../storage/to/SnapshotObjectTO.java | 3 +- .../storage/to/TemplateObjectTO.java | 1 + .../cloudstack/storage/to/VolumeObjectTO.java | 4 + .../storage/snapshot/SnapshotServiceImpl.java | 36 -- .../storage/volume/VolumeServiceImpl.java | 13 + plugins/storage/image/default/pom.xml | 5 + .../CloudStackImageStoreDriverImpl.java | 365 +---------------- plugins/storage/image/s3/pom.xml | 5 + .../driver/S3ImageStoreDriverImpl.java | 370 +---------------- plugins/storage/image/sample/pom.xml | 5 + .../driver/SampleImageStoreDriverImpl.java | 94 +---- plugins/storage/image/swift/pom.xml | 5 + .../driver/SwiftImageStoreDriverImpl.java | 382 +----------------- .../com/cloud/storage/StorageManagerImpl.java | 5 +- .../storage/snapshot/SnapshotManagerImpl.java | 10 - .../template/HypervisorTemplateAdapter.java | 32 +- .../resource/NfsSecondaryStorageResource.java | 67 +-- 19 files changed, 118 insertions(+), 1342 deletions(-) delete mode 100644 core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java diff --git a/api/src/com/cloud/agent/api/to/DataTO.java b/api/src/com/cloud/agent/api/to/DataTO.java index bd9a16bfc11..21e802fde1f 100644 --- a/api/src/com/cloud/agent/api/to/DataTO.java +++ b/api/src/com/cloud/agent/api/to/DataTO.java @@ -25,4 +25,6 @@ public interface DataTO { * @return */ String getPath(); + + long getId(); } diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java deleted file mode 100644 index 2fcb62a534f..00000000000 --- a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand2.java +++ /dev/null @@ -1,56 +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 com.cloud.agent.api; - -import com.cloud.agent.api.to.DataStoreTO; - -/** - * This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server - * This currently assumes that the secondary storage are mounted on the XenServer. - */ -public class DeleteSnapshotBackupCommand2 extends Command { - private DataStoreTO store; - private String snapshotPath; - - - public DeleteSnapshotBackupCommand2() { - } - - - public DeleteSnapshotBackupCommand2(DataStoreTO store, - String snapshotPath) - { - this.store = store; - this.snapshotPath = snapshotPath; - } - - - public DataStoreTO getDataStore(){ - return store; - } - - - public String getSnapshotPath() { - return snapshotPath; - } - - - @Override - public boolean executeInSequence() { - return true; - } -} diff --git a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java index f8f622c9307..fcaa320949a 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/SnapshotObjectTO.java @@ -11,7 +11,7 @@ // 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 +// KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. package org.apache.cloudstack.storage.to; @@ -93,6 +93,7 @@ public class SnapshotObjectTO implements DataTO { this.vmName = vmName; } + @Override public long getId() { return id; } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index fefb0ad3ec4..0effd8d567d 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -80,6 +80,7 @@ public class TemplateObjectTO implements DataTO { return this.uuid; } + @Override public long getId() { return id; } diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index be268ffc677..549481e0fa6 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -65,6 +65,7 @@ public class VolumeObjectTO implements DataTO { return this.uuid; } + @Override public String getPath() { return this.path; } @@ -73,6 +74,7 @@ public class VolumeObjectTO implements DataTO { return this.volumeType; } + @Override public DataStoreTO getDataStore() { return this.dataStore; } @@ -89,6 +91,7 @@ public class VolumeObjectTO implements DataTO { return this.size; } + @Override public DataObjectType getObjectType() { return DataObjectType.VOLUME; } @@ -141,6 +144,7 @@ public class VolumeObjectTO implements DataTO { this.chainInfo = chainInfo; } + @Override public long getId() { return id; } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index 545a6a0ecef..ed538114177 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -342,42 +342,6 @@ public class SnapshotServiceImpl implements SnapshotService { return null; } - @DB - protected boolean destroySnapshotBackUp(SnapshotVO snapshot) { - SnapshotDataStoreVO snapshotStore = this._snapshotStoreDao - .findBySnapshot(snapshot.getId(), DataStoreRole.Image); - if (snapshotStore == null) { - s_logger.debug("Can't find snapshot" + snapshot.getId() + " backed up into image store"); - return false; - } - DataStore store = this.dataStoreMgr.getDataStore(snapshotStore.getDataStoreId(), DataStoreRole.Image); - if (store == null) { - s_logger.debug("Can't find mage store " + snapshotStore.getDataStoreId()); - return false; - } - - try { - SnapshotInfo snapshotInfo = this.snapshotfactory.getSnapshot(snapshot.getId(), store); - snapshotInfo.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested); - - AsyncCallFuture future = new AsyncCallFuture(); - DeleteSnapshotContext context = new DeleteSnapshotContext(null, snapshotInfo, - future); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setCallback(caller.getTarget().deleteSnapshotCallback(null, null)).setContext(context); - - store.getDriver().deleteAsync(snapshotInfo, caller); - - SnapshotResult result = future.get(); - if (result.isFailed()) { - s_logger.debug("Failed to delete snapsoht: " + result.getResult()); - } - return result.isSuccess(); - } catch (Exception e) { - s_logger.debug("Failed to delete snapshot", e); - return false; - } - } protected Void deleteSnapshotCallback(AsyncCallbackDispatcher callback, DeleteSnapshotContext context) { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 99aac17e3da..04e97dd071d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -55,6 +55,7 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.to.VirtualMachineTO; @@ -67,6 +68,7 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.host.Host; import com.cloud.storage.DataStoreRole; import com.cloud.storage.StoragePool; +import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; @@ -78,6 +80,7 @@ import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.dao.VMInstanceDao; @Component @@ -214,6 +217,16 @@ public class VolumeServiceImpl implements VolumeService { return future; } + // Find out if the volume is at state of download_in_progress on secondary storage + VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId()); + if (volumeStore != null) { + if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { + s_logger.debug("Volume: " + volume.getName() + " is currently being uploaded; cant' delete it."); + future.complete(result); + return future; + } + } + VolumeVO vol = volDao.findById(volume.getId()); String volumePath = vol.getPath(); diff --git a/plugins/storage/image/default/pom.xml b/plugins/storage/image/default/pom.xml index d1b079d05e6..f51d8f55a1d 100644 --- a/plugins/storage/image/default/pom.xml +++ b/plugins/storage/image/default/pom.xml @@ -20,6 +20,11 @@ ../../../pom.xml + + org.apache.cloudstack + cloud-engine-storage + ${project.version} + org.apache.cloudstack cloud-engine-storage-image diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java index 243017fb58e..aa2d533c255 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackImageStoreDriverImpl.java @@ -18,116 +18,35 @@ */ package org.apache.cloudstack.storage.datastore.driver; -import java.util.Date; -import java.util.List; -import java.util.Set; import java.util.UUID; import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; -import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; -import org.apache.cloudstack.storage.image.store.TemplateObject; -import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.log4j.Logger; +import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl; -import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.NfsTO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; -import com.cloud.host.dao.HostDao; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.Upload.Mode; -import com.cloud.storage.Upload.Status; -import com.cloud.storage.Upload.Type; -import com.cloud.storage.UploadVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.user.Account; -import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; -public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { +public class CloudStackImageStoreDriverImpl extends BaseImageStoreDriverImpl { private static final Logger s_logger = Logger.getLogger(CloudStackImageStoreDriverImpl.class); - @Inject - VMTemplateZoneDao templateZoneDao; - @Inject - VMTemplateDao templateDao; - @Inject - DownloadMonitor _downloadMonitor; - @Inject - VolumeDao volumeDao; - @Inject - VolumeDataStoreDao _volumeStoreDao; - @Inject - HostDao hostDao; - @Inject - SnapshotDao snapshotDao; - @Inject - AgentManager agentMgr; - @Inject - SnapshotManager snapshotMgr; - @Inject - AccountDao _accountDao; + @Inject ConfigurationDao _configDao; @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject - TemplateDataStoreDao _templateStoreDao; - @Inject EndPointSelector _epSelector; - @Inject - DataStoreManager _dataStoreMgr; - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } - - @Override - public DataTO getTO(DataObject data) { - return null; - } @Override public DataStoreTO getStoreTO(DataStore store) { @@ -138,284 +57,6 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver { return nfsTO; } - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } - - class CreateContext extends AsyncRpcConext { - final DataObject data; - - public CreateContext(AsyncCompletionCallback callback, DataObject data) { - super(callback); - this.data = data; - } - } - - @Override - public void createAsync(DataObject data, AsyncCompletionCallback callback) { - CreateContext context = new CreateContext(callback, data); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setContext(context); - if (data.getType() == DataObjectType.TEMPLATE) { - caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); - _downloadMonitor.downloadTemplateToStorage(data, caller); - } else if (data.getType() == DataObjectType.VOLUME) { - caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); - _downloadMonitor.downloadVolumeToStorage(data, caller); - } - } - - protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); - - TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); - if (tmpltStoreVO != null) { - TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); - // update size in vm_template table - VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); - tmlptUpdater.setSize(answer.getTemplateSize()); - templateDao.update(obj.getId(), tmlptUpdater); - } - - AsyncCompletionCallback caller = context.getParentCallback(); - - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - templateDao.update(obj.getId(), templateDaoBuilder); - } - - CreateCmdResult result = new CreateCmdResult(null, null); - caller.complete(result); - } - return null; - } - - protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); - - VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); - if (volStoreVO != null) { - VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); - // update size in volume table - VolumeVO volUpdater = volumeDao.createForUpdate(); - volUpdater.setSize(answer.getTemplateSize()); - volumeDao.update(obj.getId(), volUpdater); - } - - AsyncCompletionCallback caller = context.getParentCallback(); - - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - CreateCmdResult result = new CreateCmdResult(null, null); - caller.complete(result); - } - return null; - } - - private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { - VolumeVO vol = volumeDao.findById(data.getId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Expunging " + vol); - } - - // Find out if the volume is present on secondary storage - VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId()); - if (volumeStore != null) { - if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - DataStore store = _dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); - EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(), - volumeStore.getInstallPath()); - Answer answer = ep.sendMessage(dtCommand); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " + volumeStore + " due to " - + ((answer == null) ? "answer is null" : answer.getDetails())); - return; - } - } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); - } - - CommandResult result = new CommandResult(); - callback.complete(result); - return; - } - } - - private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { - - TemplateObject templateObj = (TemplateObject) data; - VMTemplateVO template = templateObj.getImage(); - ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); - long storeId = store.getId(); - Long sZoneId = store.getDataCenterId(); - long templateId = template.getId(); - - Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); - String eventType = ""; - - if (template.getFormat().equals(ImageFormat.ISO)) { - eventType = EventTypes.EVENT_ISO_DELETE; - } else { - eventType = EventTypes.EVENT_TEMPLATE_DELETE; - } - - // TODO: need to understand why we need to mark destroyed in - // template_store_ref table here instead of in callback. - // Currently I did that in callback, so I removed previous code to mark - // template_host_ref - if (sZoneId != null) { - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - } - - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), - template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); - - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - result.setSuccess(false); - result.setResult("Delete template failed"); - callback.complete(result); - - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - result.setSuccess(true); - callback.complete(result); - } - - List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } - } - } - - } - - private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - SnapshotObject snapshotObj = (SnapshotObject) data; - DataStore secStore = snapshotObj.getDataStore(); - CommandResult result = new CommandResult(); - SnapshotVO snapshot = snapshotObj.getSnapshotVO(); - - if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotObj.getId() - + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotObj.getId()); - callback.complete(result); - return; - } - - try { - String backupOfSnapshot = snapshotObj.getPath(); - if (backupOfSnapshot == null) { - callback.complete(result); - return; - } - - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot); - EndPoint ep = _epSelector.select(secStore); - Answer answer = ep.sendMessage(cmd); - - if (answer != null && !answer.getResult()) { - result.setResult(answer.getDetails()); - } - } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); - result.setResult(e.toString()); - } - callback.complete(result); - } - - @Override - public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { - if (data.getType() == DataObjectType.VOLUME) { - deleteVolume(data, callback); - } else if (data.getType() == DataObjectType.TEMPLATE) { - deleteTemplate(data, callback); - } else if (data.getType() == DataObjectType.SNAPSHOT) { - deleteSnapshot(data, callback); - } - } - - @Override - public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } - - @Override - public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } - @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { // find an endpoint to send command diff --git a/plugins/storage/image/s3/pom.xml b/plugins/storage/image/s3/pom.xml index 7f5b9c4b333..ad42e6fa376 100644 --- a/plugins/storage/image/s3/pom.xml +++ b/plugins/storage/image/s3/pom.xml @@ -27,6 +27,11 @@ ../../../pom.xml + + org.apache.cloudstack + cloud-engine-storage + ${project.version} + org.apache.cloudstack cloud-engine-storage-image diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 8cf4835dd53..49da980dfd8 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -18,118 +18,29 @@ */ package org.apache.cloudstack.storage.datastore.driver; -import java.util.Date; -import java.util.List; import java.util.Map; -import java.util.Set; - import javax.inject.Inject; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; -import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; -import org.apache.cloudstack.storage.image.store.TemplateObject; -import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.log4j.Logger; import com.amazonaws.services.s3.model.CannedAccessControlList; -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand2; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.S3TO; -import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; -import com.cloud.host.dao.HostDao; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.SnapshotVO; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.user.Account; -import com.cloud.user.dao.AccountDao; import com.cloud.utils.S3Utils; import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.dao.UserVmDao; -public class S3ImageStoreDriverImpl implements ImageStoreDriver { +public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl { private static final Logger s_logger = Logger.getLogger(S3ImageStoreDriverImpl.class); - @Inject - VMTemplateZoneDao templateZoneDao; - @Inject - VMTemplateDao templateDao; - @Inject - DownloadMonitor _downloadMonitor; + @Inject ImageStoreDetailsDao _imageStoreDetailsDao; - @Inject - VolumeDao volumeDao; - @Inject - VolumeDataStoreDao _volumeStoreDao; - @Inject - HostDao hostDao; - @Inject - SnapshotDao snapshotDao; - @Inject - AgentManager agentMgr; - @Inject - SnapshotManager snapshotMgr; - @Inject - AccountDao _accountDao; - @Inject - UserVmDao _userVmDao; - @Inject - UserVmJoinDao _userVmJoinDao; - @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject - TemplateDataStoreDao _templateStoreDao; - @Inject - EndPointSelector _epSelector; - @Inject - DataStoreManager _dataStoreMgr; - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } - - @Override - public DataTO getTO(DataObject data) { - return null; - } @Override public DataStoreTO getStoreTO(DataStore store) { @@ -148,281 +59,6 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } - - class CreateContext extends AsyncRpcConext { - final DataObject data; - - public CreateContext(AsyncCompletionCallback callback, DataObject data) { - super(callback); - this.data = data; - } - } - - @Override - public void createAsync(DataObject data, AsyncCompletionCallback callback) { - - CreateContext context = new CreateContext(callback, data); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher.create(this); - caller.setContext(context); - if (data.getType() == DataObjectType.TEMPLATE) { - caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); - _downloadMonitor.downloadTemplateToStorage(data, caller); - } else if (data.getType() == DataObjectType.VOLUME) { - caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); - _downloadMonitor.downloadVolumeToStorage(data, caller); - } - } - - private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { - VolumeVO vol = volumeDao.findById(data.getId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Expunging " + vol); - } - - // Find out if the volume is present on secondary storage - VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId()); - if (volumeStore != null) { - if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - DataStore store = _dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); - EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(), - volumeStore.getInstallPath()); - Answer answer = ep.sendMessage(dtCommand); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " + volumeStore + " due to " - + ((answer == null) ? "answer is null" : answer.getDetails())); - return; - } - } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); - } - _volumeStoreDao.remove(volumeStore.getId()); - volumeDao.remove(vol.getId()); - CommandResult result = new CommandResult(); - callback.complete(result); - return; - } - } - - protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); - - TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); - if (tmpltStoreVO != null) { - TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); - // update size in vm_template table - VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); - tmlptUpdater.setSize(answer.getTemplateSize()); - templateDao.update(obj.getId(), tmlptUpdater); - } - - AsyncCompletionCallback caller = context.getParentCallback(); - - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - templateDao.update(obj.getId(), templateDaoBuilder); - } - - CreateCmdResult result = new CreateCmdResult(null, null); - caller.complete(result); - } - return null; - } - - protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); - - VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); - if (volStoreVO != null) { - VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); - // update size in volume table - VolumeVO volUpdater = volumeDao.createForUpdate(); - volUpdater.setSize(answer.getTemplateSize()); - volumeDao.update(obj.getId(), volUpdater); - } - - AsyncCompletionCallback caller = context.getParentCallback(); - - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - CreateCmdResult result = new CreateCmdResult(null, null); - caller.complete(result); - } - return null; - } - - private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { - TemplateObject templateObj = (TemplateObject) data; - VMTemplateVO template = templateObj.getImage(); - ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); - long storeId = store.getId(); - Long sZoneId = store.getDataCenterId(); - long templateId = template.getId(); - - Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); - String eventType = ""; - - if (template.getFormat().equals(ImageFormat.ISO)) { - eventType = EventTypes.EVENT_ISO_DELETE; - } else { - eventType = EventTypes.EVENT_TEMPLATE_DELETE; - } - - if (sZoneId != null) { - // TODO: how to handle region wide usage data where sZoneId == null - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - } - - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), - template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); - - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - result.setSuccess(false); - result.setResult("Delete template failed"); - callback.complete(result); - - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - result.setSuccess(true); - callback.complete(result); - } - - // for S3, a template can be associated with multiple zones - List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } - } - } - } - - private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - SnapshotObject snapshotObj = (SnapshotObject) data; - DataStore secStore = snapshotObj.getDataStore(); - CommandResult result = new CommandResult(); - SnapshotVO snapshot = snapshotObj.getSnapshotVO(); - - if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotObj.getId() - + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotObj.getId()); - callback.complete(result); - return; - } - - try { - - String backupOfSnapshot = snapshotObj.getPath(); - if (backupOfSnapshot == null) { - callback.complete(result); - return; - } - - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot); - EndPoint ep = _epSelector.select(secStore); - Answer answer = ep.sendMessage(cmd); - - if (answer != null) { - result.setResult(answer.getDetails()); - } - } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); - result.setResult(e.toString()); - } - callback.complete(result); - } - - @Override - public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { - if (data.getType() == DataObjectType.VOLUME) { - deleteVolume(data, callback); - } else if (data.getType() == DataObjectType.TEMPLATE) { - deleteTemplate(data, callback); - } else if (data.getType() == DataObjectType.SNAPSHOT) { - deleteSnapshot(data, callback); - } - } - - @Override - public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } - - @Override - public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { diff --git a/plugins/storage/image/sample/pom.xml b/plugins/storage/image/sample/pom.xml index d9eab9b45e5..44b50b09220 100644 --- a/plugins/storage/image/sample/pom.xml +++ b/plugins/storage/image/sample/pom.xml @@ -20,6 +20,11 @@ ../../../pom.xml + + org.apache.cloudstack + cloud-engine-storage + ${project.version} + org.apache.cloudstack cloud-engine-storage-image diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index abc8741ac5a..2dae3c84bc5 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -18,30 +18,17 @@ */ package org.apache.cloudstack.storage.datastore.driver; -import java.util.Set; - import javax.inject.Inject; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.command.CreateObjectAnswer; -import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.image.ImageStoreDriver; - -import com.cloud.agent.api.to.DataObjectType; +import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.dao.VMTemplateDao; //http-read-only based image store -public class SampleImageStoreDriverImpl implements ImageStoreDriver { +public class SampleImageStoreDriverImpl extends BaseImageStoreDriverImpl { @Inject EndPointSelector selector; @Inject @@ -50,10 +37,6 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { public SampleImageStoreDriverImpl() { } - @Override - public DataTO getTO(DataObject data) { - return null; - } @Override public DataStoreTO getStoreTO(DataStore store) { @@ -61,80 +44,7 @@ public class SampleImageStoreDriverImpl implements ImageStoreDriver { return null; } - @Override - public String grantAccess(DataObject data, EndPoint ep) { - return data.getUri(); - } - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return true; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void createAsync(DataObject data, AsyncCompletionCallback callback) { - // for default http data store, can create http based template/iso - CreateCmdResult result = new CreateCmdResult("", null); - if (!data.getUri().startsWith("http")) { - result.setResult("can't register an image which is not a http link"); - callback.complete(result); - return; - } - - if (data.getSize() == null && data.getType() == DataObjectType.TEMPLATE) { - // the template size is unknown during registration, need to find - // out the size of template - EndPoint ep = selector.select(data); - if (ep == null) { - result.setResult("can't find storage client for:" + data.getId() + "," + data.getType()); - callback.complete(result); - return; - } - CreateObjectCommand createCmd = new CreateObjectCommand(data.getTO()); - CreateObjectAnswer answer = (CreateObjectAnswer) ep.sendMessage(createCmd); - if (answer.getResult()) { - // update imagestorevo - - result = new CreateCmdResult(null, null); - } else { - result.setResult(answer.getDetails()); - } - - } - - callback.complete(result); - } - - @Override - public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { - CommandResult result = new CommandResult(); - callback.complete(result); - } - - @Override - public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } - - @Override - public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { diff --git a/plugins/storage/image/swift/pom.xml b/plugins/storage/image/swift/pom.xml index 6254ccef6a6..4e3907fd808 100644 --- a/plugins/storage/image/swift/pom.xml +++ b/plugins/storage/image/swift/pom.xml @@ -20,6 +20,11 @@ ../../../pom.xml + + org.apache.cloudstack + cloud-engine-storage + ${project.version} + org.apache.cloudstack cloud-engine-storage-image diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index bd48c446d08..bd5a14a277a 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -18,125 +18,27 @@ */ package org.apache.cloudstack.storage.datastore.driver; -import java.util.Date; -import java.util.List; import java.util.Map; -import java.util.Set; - import javax.inject.Inject; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.command.CommandResult; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; -import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; -import org.apache.cloudstack.storage.image.store.TemplateObject; -import org.apache.cloudstack.storage.snapshot.SnapshotObject; import org.apache.log4j.Logger; -import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand2; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; -import com.cloud.agent.api.storage.DownloadAnswer; -import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.SwiftTO; -import com.cloud.api.query.dao.UserVmJoinDao; -import com.cloud.event.EventTypes; -import com.cloud.event.UsageEventUtils; import com.cloud.exception.UnsupportedServiceException; -import com.cloud.host.dao.HostDao; import com.cloud.storage.Storage.ImageFormat; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VMTemplateStorageResourceAssoc; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.download.DownloadMonitor; -import com.cloud.storage.s3.S3Manager; -import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.storage.swift.SwiftManager; -import com.cloud.user.Account; -import com.cloud.user.dao.AccountDao; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.dao.UserVmDao; -public class SwiftImageStoreDriverImpl implements ImageStoreDriver { +public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl { private static final Logger s_logger = Logger.getLogger(SwiftImageStoreDriverImpl.class); - @Inject - VMTemplateZoneDao templateZoneDao; - @Inject - VMTemplateDao templateDao; - @Inject - DownloadMonitor _downloadMonitor; + @Inject ImageStoreDetailsDao _imageStoreDetailsDao; - @Inject - VolumeDao volumeDao; - @Inject - VolumeDataStoreDao _volumeStoreDao; - @Inject - HostDao hostDao; - @Inject - SnapshotDao snapshotDao; - @Inject - AgentManager agentMgr; - @Inject - SnapshotManager snapshotMgr; - @Inject - private SwiftManager _swiftMgr; - @Inject - private S3Manager _s3Mgr; - @Inject - AccountDao _accountDao; - @Inject - UserVmDao _userVmDao; - @Inject - UserVmJoinDao _userVmJoinDao; - @Inject - SecondaryStorageVmManager _ssvmMgr; - @Inject - private AgentManager _agentMgr; - @Inject - TemplateDataStoreDao _templateStoreDao; - @Inject - EndPointSelector _epSelector; - @Inject - DataStoreManager _dataStoreMgr; - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } - - @Override - public DataTO getTO(DataObject data) { - return null; - } @Override public DataStoreTO getStoreTO(DataStore store) { @@ -146,284 +48,6 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { details.get(ApiConstants.USERNAME), details.get(ApiConstants.KEY)); } - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } - - class CreateContext extends AsyncRpcConext { - final DataObject data; - - public CreateContext(AsyncCompletionCallback callback, DataObject data) { - super(callback); - this.data = data; - } - } - - @Override - public void createAsync(DataObject data, AsyncCompletionCallback callback) { - CreateContext context = new CreateContext(callback, data); - AsyncCallbackDispatcher caller = AsyncCallbackDispatcher - .create(this); - caller.setContext(context); - if (data.getType() == DataObjectType.TEMPLATE) { - caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); - _downloadMonitor.downloadTemplateToStorage(data, caller); - } else if (data.getType() == DataObjectType.VOLUME) { - caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); - _downloadMonitor.downloadVolumeToStorage(data, caller); - } - } - - protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); - - TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); - if (tmpltStoreVO != null) { - TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); - // update size in vm_template table - VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); - tmlptUpdater.setSize(answer.getTemplateSize()); - templateDao.update(obj.getId(), tmlptUpdater); - } - - AsyncCompletionCallback caller = context.getParentCallback(); - - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - if (answer.getCheckSum() != null) { - VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); - templateDaoBuilder.setChecksum(answer.getCheckSum()); - templateDao.update(obj.getId(), templateDaoBuilder); - } - - CreateCmdResult result = new CreateCmdResult(null, null); - caller.complete(result); - } - return null; - } - - protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, - CreateContext context) { - DownloadAnswer answer = callback.getResult(); - DataObject obj = context.data; - DataStore store = obj.getDataStore(); - - VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); - if (volStoreVO != null) { - VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); - updateBuilder.setDownloadPercent(answer.getDownloadPct()); - updateBuilder.setDownloadState(answer.getDownloadStatus()); - updateBuilder.setLastUpdated(new Date()); - updateBuilder.setErrorString(answer.getErrorString()); - updateBuilder.setJobId(answer.getJobId()); - updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); - updateBuilder.setInstallPath(answer.getInstallPath()); - updateBuilder.setSize(answer.getTemplateSize()); - updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); - _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); - // update size in volume table - VolumeVO volUpdater = volumeDao.createForUpdate(); - volUpdater.setSize(answer.getTemplateSize()); - volumeDao.update(obj.getId(), volUpdater); - } - - AsyncCompletionCallback caller = context.getParentCallback(); - - if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED - || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { - CreateCmdResult result = new CreateCmdResult(null, null); - result.setSuccess(false); - result.setResult(answer.getErrorString()); - caller.complete(result); - } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - CreateCmdResult result = new CreateCmdResult(null, null); - caller.complete(result); - } - return null; - } - - private void deleteVolume(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - VolumeVO vol = volumeDao.findById(data.getId()); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Expunging " + vol); - } - - // Find out if the volume is present on secondary storage - VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(vol.getId()); - if (volumeStore != null) { - if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - DataStore store = this._dataStoreMgr.getDataStore(volumeStore.getDataStoreId(), DataStoreRole.Image); - EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand dtCommand = new DeleteVolumeCommand(store.getTO(), volumeStore.getVolumeId(), - volumeStore.getInstallPath()); - Answer answer = ep.sendMessage(dtCommand); - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to delete " + volumeStore + " due to " - + ((answer == null) ? "answer is null" : answer.getDetails())); - return; - } - } else if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) { - s_logger.debug("Volume: " + vol.getName() + " is currently being uploaded; cant' delete it."); - throw new CloudRuntimeException("Please specify a volume that is not currently being uploaded."); - } - _volumeStoreDao.remove(volumeStore.getId()); - volumeDao.remove(vol.getId()); - CommandResult result = new CommandResult(); - callback.complete(result); - return; - } - } - - private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { - TemplateObject templateObj = (TemplateObject) data; - VMTemplateVO template = templateObj.getImage(); - ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); - long storeId = store.getId(); - Long sZoneId = store.getDataCenterId(); - long templateId = template.getId(); - - Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); - String eventType = ""; - - if (template.getFormat().equals(ImageFormat.ISO)) { - eventType = EventTypes.EVENT_ISO_DELETE; - } else { - eventType = EventTypes.EVENT_TEMPLATE_DELETE; - } - - // TODO: need to understand why we need to mark destroyed in - // template_store_ref table here instead of in callback. - // Currently I did that in callback, so I removed previous code to mark - // template_host_ref - if (sZoneId != null) { - UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); - } - - // get installpath of this template on image store - TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); - String installPath = tmplStore.getInstallPath(); - if (installPath != null) { - DeleteTemplateCommand cmd = new DeleteTemplateCommand(store.getTO(), installPath, template.getId(), - template.getAccountId()); - EndPoint ep = _epSelector.select(templateObj); - Answer answer = ep.sendMessage(cmd); - - if (answer == null || !answer.getResult()) { - s_logger.debug("Failed to deleted template at store: " + store.getName()); - CommandResult result = new CommandResult(); - // result.setSucess(false); - result.setResult("Delete template failed"); - callback.complete(result); - - } else { - s_logger.debug("Deleted template at: " + installPath); - CommandResult result = new CommandResult(); - // result.setSucess(true); - callback.complete(result); - } - - // for Swift, a template can be associated with multiple zones - List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - templateZoneDao.remove(templateZone.getId()); - } - } - } - } - - private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { - SnapshotObject snapshotObj = (SnapshotObject) data; - DataStore secStore = snapshotObj.getDataStore(); - CommandResult result = new CommandResult(); - SnapshotVO snapshot = snapshotObj.getSnapshotVO(); - - if (snapshot == null) { - s_logger.debug("Destroying snapshot " + snapshotObj.getId() - + " backup failed due to unable to find snapshot "); - result.setResult("Unable to find snapshot: " + snapshotObj.getId()); - callback.complete(result); - return; - } - - try { - String backupOfSnapshot = snapshotObj.getPath(); - if (backupOfSnapshot == null) { - callback.complete(result); - return; - } - - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(secStore.getTO(), backupOfSnapshot); - EndPoint ep = _epSelector.select(secStore); - Answer answer = ep.sendMessage(cmd); - - if (answer != null) { - result.setResult(answer.getDetails()); - } - } catch (Exception e) { - s_logger.debug("failed to delete snapshot: " + snapshotObj.getId() + ": " + e.toString()); - result.setResult(e.toString()); - } - callback.complete(result); - } - - @Override - public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { - if (data.getType() == DataObjectType.VOLUME) { - deleteVolume(data, callback); - } else if (data.getType() == DataObjectType.TEMPLATE) { - deleteTemplate(data, callback); - } else if (data.getType() == DataObjectType.SNAPSHOT) { - deleteSnapshot(data, callback); - } - } - - @Override - public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } - - @Override - public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub - return false; - } - - @Override - public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - - } @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index 35fa3235717..d5b3f236170 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -71,6 +71,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.framework.async.AsyncCallFuture; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; @@ -88,8 +89,6 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.StoragePoolInfo; import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; @@ -1198,7 +1197,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C if (installPath != null) { EndPoint ep = _epSelector.select(store); - DeleteSnapshotBackupCommand2 cmd = new DeleteSnapshotBackupCommand2(store.getTO(), destroyedSnapshotStoreVO.getInstallPath()); + DeleteCommand cmd = new DeleteCommand(snap.getTO()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + destroyedSnapshotStoreVO + " due to " diff --git a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java index a87f542dcba..a7e61374dfb 100755 --- a/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java +++ b/server/src/com/cloud/storage/snapshot/SnapshotManagerImpl.java @@ -17,7 +17,6 @@ package com.cloud.storage.snapshot; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -45,27 +44,19 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.DeleteSnapshotsDirCommand; -import com.cloud.agent.api.DownloadSnapshotFromS3Command; -import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; import com.cloud.alert.AlertManager; import com.cloud.api.commands.ListRecurringSnapshotScheduleCmd; import com.cloud.configuration.Config; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; @@ -83,7 +74,6 @@ import com.cloud.exception.StorageUnavailableException; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.resource.ResourceManager; import com.cloud.server.ResourceTag.TaggedResourceType; diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java index e1d535b2a1a..92148c3f83c 100755 --- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java +++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java @@ -16,11 +16,6 @@ // under the License. package com.cloud.template; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.UnknownHostException; import java.util.List; import java.util.concurrent.ExecutionException; @@ -47,6 +42,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; +import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -54,14 +50,19 @@ import com.cloud.agent.api.storage.PrepareOVAPackingCommand; import com.cloud.alert.AlertManager; import com.cloud.configuration.Resource.ResourceType; import com.cloud.dc.DataCenterVO; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceAllocationException; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.TemplateProfile; +import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.user.Account; import com.cloud.utils.UriUtils; @@ -79,6 +80,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { @Inject TemplateDataFactory imageFactory; @Inject TemplateManager templateMgr; @Inject AlertManager alertMgr; + @Inject VMTemplateZoneDao templateZoneDao; @Inject EndPointSelector _epSelector; @@ -219,8 +221,20 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { } } + String eventType = ""; + if (template.getFormat().equals(ImageFormat.ISO)) { + eventType = EventTypes.EVENT_ISO_DELETE; + } else { + eventType = EventTypes.EVENT_TEMPLATE_DELETE; + } for (DataStore imageStore : imageStores) { + // publish zone-wide usage event + Long sZoneId = ((ImageStoreEntity)imageStore).getDataCenterId(); + if (sZoneId != null) { + UsageEventUtils.publishUsageEvent(eventType, template.getAccountId(), sZoneId, template.getId(), null, null, null); + } + s_logger.info("Delete template from image store: " + imageStore.getName()); AsyncCallFuture future = this.imageService .deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore)); @@ -229,6 +243,14 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase { success = result.isSuccess(); if ( !success ) break; + + // remove from template_zone_ref + List templateZones = templateZoneDao.listByZoneTemplate(sZoneId, template.getId()); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } } catch (InterruptedException e) { s_logger.debug("delete template Failed", e); throw new CloudRuntimeException("delete template Failed", e); diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 228024e4edb..ff20800cf6c 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.storage.resource; -import static com.cloud.utils.S3Utils.getDirectory; import static com.cloud.utils.S3Utils.putFile; import static com.cloud.utils.StringUtils.join; import static com.cloud.utils.db.GlobalLock.executeWithNoWaitLock; @@ -28,7 +27,6 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java.io.FileWriter; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; @@ -68,7 +66,6 @@ import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand2; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DownloadSnapshotFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; @@ -87,18 +84,14 @@ import com.cloud.agent.api.SecStorageSetupCommand.Certificates; import com.cloud.agent.api.SecStorageVMSetupCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupSecondaryStorageCommand; -import com.cloud.agent.api.UploadTemplateToS3FromSecondaryStorageCommand; import com.cloud.agent.api.UploadTemplateToSwiftFromSecondaryStorageCommand; import com.cloud.agent.api.storage.CreateEntityDownloadURLCommand; import com.cloud.agent.api.storage.DeleteEntityDownloadURLCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.UploadCommand; -import com.cloud.agent.api.storage.ssCommand; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; @@ -120,9 +113,7 @@ import com.cloud.storage.template.TemplateProp; import com.cloud.storage.template.VhdProcessor; import com.cloud.utils.NumbersUtil; import com.cloud.utils.S3Utils; -import com.cloud.utils.S3Utils.ClientOptions; import com.cloud.utils.S3Utils.FileNamingStrategy; -import com.cloud.utils.S3Utils.ObjectNamingStrategy; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.OutputInterpreter; @@ -188,10 +179,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((GetStorageStatsCommand) cmd); } else if (cmd instanceof CheckHealthCommand) { return new CheckHealthAnswer((CheckHealthCommand) cmd, true); - } else if (cmd instanceof DeleteTemplateCommand) { - return execute((DeleteTemplateCommand) cmd); - } else if (cmd instanceof DeleteVolumeCommand) { - return execute((DeleteVolumeCommand) cmd); } else if (cmd instanceof ReadyCommand) { return new ReadyAnswer((ReadyCommand) cmd); } else if (cmd instanceof SecStorageFirewallCfgCommand) { @@ -212,8 +199,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((DownloadSnapshotFromS3Command) cmd); } else if (cmd instanceof DeleteSnapshotBackupCommand) { return execute((DeleteSnapshotBackupCommand) cmd); - } else if (cmd instanceof DeleteSnapshotBackupCommand2) { - return execute((DeleteSnapshotBackupCommand2) cmd); } else if (cmd instanceof DeleteSnapshotsDirCommand) { return execute((DeleteSnapshotsDirCommand) cmd); } else if (cmd instanceof DownloadTemplateFromSwiftToSecondaryStorageCommand) { @@ -222,6 +207,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((UploadTemplateToSwiftFromSecondaryStorageCommand) cmd); } else if (cmd instanceof CopyCommand) { return execute((CopyCommand) cmd); + } else if (cmd instanceof DeleteCommand) { + return execute((DeleteCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); } @@ -1228,11 +1215,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return join("_", "SNAPSHOT", accountId, volumeId); } - protected Answer execute(final DeleteSnapshotBackupCommand2 cmd) { - DataStoreTO dstore = cmd.getDataStore(); + protected Answer deleteSnapshot(final DeleteCommand cmd) { + DataTO obj = cmd.getData(); + DataStoreTO dstore = obj.getDataStore(); if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO) dstore; - String relativeSnapshotPath = cmd.getSnapshotPath(); + String relativeSnapshotPath = obj.getPath(); String parent = getRootDir(nfs.getUrl()); if (relativeSnapshotPath.startsWith(File.separator)) { @@ -1258,7 +1246,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, null); } else if (dstore instanceof S3TO) { final S3TO s3 = (S3TO) dstore; - final String path = cmd.getSnapshotPath(); + final String path = obj.getPath(); final String bucket = s3.getBucketName(); try { S3Utils.deleteObject(s3, bucket, path); @@ -1270,7 +1258,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, false, errorMessage); } } else if (dstore instanceof SwiftTO) { - String path = cmd.getSnapshotPath(); + String path = obj.getPath(); String filename = StringUtils.substringAfterLast(path, "/"); // assuming // that // the @@ -1585,11 +1573,26 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - protected Answer execute(final DeleteTemplateCommand cmd) { - DataStoreTO dstore = cmd.getDataStore(); + protected Answer execute(final DeleteCommand cmd){ + DataTO obj = cmd.getData(); + DataObjectType objType = obj.getObjectType(); + switch (objType){ + case TEMPLATE: + return deleteTemplate(cmd); + case VOLUME: + return deleteVolume(cmd); + case SNAPSHOT: + return deleteSnapshot(cmd); + } + return Answer.createUnsupportedCommandAnswer(cmd); + } + + protected Answer deleteTemplate(DeleteCommand cmd) { + DataTO obj = cmd.getData(); + DataStoreTO dstore = obj.getDataStore(); if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO) dstore; - String relativeTemplatePath = cmd.getTemplatePath(); + String relativeTemplatePath = obj.getPath(); String parent = getRootDir(nfs.getUrl()); if (relativeTemplatePath.startsWith(File.separator)) { @@ -1647,7 +1650,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, null); } else if (dstore instanceof S3TO) { final S3TO s3 = (S3TO) dstore; - final String path = cmd.getTemplatePath(); + final String path = obj.getPath(); final String bucket = s3.getBucketName(); try { S3Utils.deleteDirectory(s3, bucket, path); @@ -1660,7 +1663,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } else if (dstore instanceof SwiftTO) { SwiftTO swift = (SwiftTO) dstore; - String container = "T-" + cmd.getTemplateId(); + String container = "T-" + obj.getId(); String object = ""; try { @@ -1681,11 +1684,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - protected Answer execute(final DeleteVolumeCommand cmd) { - DataStoreTO dstore = cmd.getDataStore(); + protected Answer deleteVolume(final DeleteCommand cmd) { + DataTO obj = cmd.getData(); + DataStoreTO dstore = obj.getDataStore(); if (dstore instanceof NfsTO) { NfsTO nfs = (NfsTO) dstore; - String relativeVolumePath = cmd.getVolumePath(); + String relativeVolumePath = obj.getPath(); String parent = getRootDir(nfs.getUrl()); if (relativeVolumePath.startsWith(File.separator)) { @@ -1742,7 +1746,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, true, null); } else if (dstore instanceof S3TO) { final S3TO s3 = (S3TO) dstore; - final String path = cmd.getVolumePath(); + final String path = obj.getPath(); final String bucket = s3.getBucketName(); try { S3Utils.deleteDirectory(s3, bucket, path); @@ -1754,8 +1758,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new Answer(cmd, false, errorMessage); } } else if (dstore instanceof SwiftTO) { - Long volumeId = cmd.getVolumeId(); - String path = cmd.getVolumePath(); + Long volumeId = obj.getId(); + String path = obj.getPath(); String filename = StringUtils.substringAfterLast(path, "/"); // assuming // that // the @@ -1780,6 +1784,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } + @Override synchronized public String getRootDir(String secUrl) { if (!_inSystemVM) { return _parent; From 03f4c6036081a8680c32169698d729a155bb07ef Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 6 Jun 2013 18:01:25 -0700 Subject: [PATCH 278/303] Add missing new file. --- .../image/BaseImageStoreDriverImpl.java | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java new file mode 100644 index 00000000000..561c8c446b3 --- /dev/null +++ b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java @@ -0,0 +1,244 @@ +/* + * 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 java.util.Date; +import java.util.Set; +import javax.inject.Inject; + +import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; +import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; +import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; +import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.cloudstack.storage.image.ImageStoreDriver; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataObjectType; +import com.cloud.agent.api.to.DataTO; +import com.cloud.storage.VMTemplateStorageResourceAssoc; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.VolumeVO; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.download.DownloadMonitor; + +public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { + private static final Logger s_logger = Logger.getLogger(BaseImageStoreDriverImpl.class); + @Inject + VMTemplateDao templateDao; + @Inject + DownloadMonitor _downloadMonitor; + @Inject + VolumeDao volumeDao; + @Inject + VolumeDataStoreDao _volumeStoreDao; + @Inject + TemplateDataStoreDao _templateStoreDao; + @Inject + EndPointSelector _epSelector; + + @Override + public String grantAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return null; + } + + @Override + public DataTO getTO(DataObject data) { + return null; + } + + + @Override + public boolean revokeAccess(DataObject data, EndPoint ep) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Set listObjects(DataStore store) { + // TODO Auto-generated method stub + return null; + } + + class CreateContext extends AsyncRpcConext { + final DataObject data; + + public CreateContext(AsyncCompletionCallback callback, DataObject data) { + super(callback); + this.data = data; + } + } + + @Override + public void createAsync(DataObject data, AsyncCompletionCallback callback) { + CreateContext context = new CreateContext(callback, data); + AsyncCallbackDispatcher caller = AsyncCallbackDispatcher + .create(this); + caller.setContext(context); + if (data.getType() == DataObjectType.TEMPLATE) { + caller.setCallback(caller.getTarget().createTemplateAsyncCallback(null, null)); + _downloadMonitor.downloadTemplateToStorage(data, caller); + } else if (data.getType() == DataObjectType.VOLUME) { + caller.setCallback(caller.getTarget().createVolumeAsyncCallback(null, null)); + _downloadMonitor.downloadVolumeToStorage(data, caller); + } + } + + protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); + if (tmpltStoreVO != null) { + TemplateDataStoreVO updateBuilder = _templateStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _templateStoreDao.update(tmpltStoreVO.getId(), updateBuilder); + // update size in vm_template table + VMTemplateVO tmlptUpdater = templateDao.createForUpdate(); + tmlptUpdater.setSize(answer.getTemplateSize()); + templateDao.update(obj.getId(), tmlptUpdater); + } + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSuccess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + if (answer.getCheckSum() != null) { + VMTemplateVO templateDaoBuilder = templateDao.createForUpdate(); + templateDaoBuilder.setChecksum(answer.getCheckSum()); + templateDao.update(obj.getId(), templateDaoBuilder); + } + + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; + } + + protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, + CreateContext context) { + DownloadAnswer answer = callback.getResult(); + DataObject obj = context.data; + DataStore store = obj.getDataStore(); + + VolumeDataStoreVO volStoreVO = _volumeStoreDao.findByStoreVolume(store.getId(), obj.getId()); + if (volStoreVO != null) { + VolumeDataStoreVO updateBuilder = _volumeStoreDao.createForUpdate(); + updateBuilder.setDownloadPercent(answer.getDownloadPct()); + updateBuilder.setDownloadState(answer.getDownloadStatus()); + updateBuilder.setLastUpdated(new Date()); + updateBuilder.setErrorString(answer.getErrorString()); + updateBuilder.setJobId(answer.getJobId()); + updateBuilder.setLocalDownloadPath(answer.getDownloadPath()); + updateBuilder.setInstallPath(answer.getInstallPath()); + updateBuilder.setSize(answer.getTemplateSize()); + updateBuilder.setPhysicalSize(answer.getTemplatePhySicalSize()); + _volumeStoreDao.update(volStoreVO.getId(), updateBuilder); + // update size in volume table + VolumeVO volUpdater = volumeDao.createForUpdate(); + volUpdater.setSize(answer.getTemplateSize()); + volumeDao.update(obj.getId(), volUpdater); + } + + AsyncCompletionCallback caller = context.getParentCallback(); + + if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_ERROR + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.ABANDONED + || answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.UNKNOWN) { + CreateCmdResult result = new CreateCmdResult(null, null); + result.setSuccess(false); + result.setResult(answer.getErrorString()); + caller.complete(result); + } else if (answer.getDownloadStatus() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { + CreateCmdResult result = new CreateCmdResult(null, null); + caller.complete(result); + } + return null; + } + + + + @Override + public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { + DeleteCommand cmd = new DeleteCommand(data.getTO()); + + CommandResult result = new CommandResult(); + try { + EndPoint ep = _epSelector.select(data); + Answer answer = ep.sendMessage(cmd); + if (answer != null && !answer.getResult()) { + result.setResult(answer.getDetails()); + } + } catch (Exception ex) { + s_logger.debug("Unable to destoy " + data.getType().toString() + ": " + data.getId(), ex); + result.setResult(ex.toString()); + } + callback.complete(result); + } + + @Override + public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + + @Override + public boolean canCopy(DataObject srcData, DataObject destData) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void resize(DataObject data, AsyncCompletionCallback callback) { + // TODO Auto-generated method stub + + } + + +} From 1d6ed8ac20bd89625a3fb7f16c4e8d0d5f59ed90 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 7 Jun 2013 16:00:19 -0700 Subject: [PATCH 279/303] A hack to handle RiakCS bug in generating ETAG for multi-part upload object. --- utils/src/com/cloud/utils/S3Utils.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index f195215afb8..e7817f5a57c 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -222,8 +222,15 @@ public final class S3Utils { key, bucketName, tempFile.getName())); } - connection.getObject(new GetObjectRequest(bucketName, key), - tempFile); + try { + connection.getObject(new GetObjectRequest(bucketName, key), tempFile); + } catch (AmazonClientException ex) { + // hack to handle different ETAG format generated from RiakCS for multi-part uploaded object + String msg = ex.getMessage(); + if (!msg.contains("verify integrity")){ + throw ex; + } + } final File targetFile = new File(targetDirectory, namingStrategy.determineFileName(key)); @@ -245,7 +252,8 @@ public final class S3Utils { targetDirectory.getAbsolutePath(), bucketName, key), e); - } finally { + } + finally { if (tempFile != null) { tempFile.delete(); From 83b080c4b3d6b643a180a59d6c47b90d0ad4f4c3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 7 Jun 2013 16:48:47 -0700 Subject: [PATCH 280/303] Fix a path bug in s3ListTemplate and s3ListVolume, path should include filename. --- .../storage/resource/NfsSecondaryStorageResource.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index ff20800cf6c..2fca6c05cbc 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -1362,10 +1362,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Map tmpltInfos = new HashMap(); for (S3ObjectSummary objectSummary : objectSummaries) { String key = objectSummary.getKey(); - String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); + //String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); String uniqueName = this.determineS3TemplateNameFromKey(key); // TODO: isPublic value, where to get? - TemplateProp tInfo = new TemplateProp(uniqueName, installPath, objectSummary.getSize(), objectSummary.getSize(), true, false); + TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false); tmpltInfos.put(uniqueName, tInfo); } return tmpltInfos; @@ -1381,10 +1381,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Map tmpltInfos = new HashMap(); for (S3ObjectSummary objectSummary : objectSummaries) { String key = objectSummary.getKey(); - String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); + //String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); Long id = this.determineS3VolumeIdFromKey(key); // TODO: how to get volume template name - TemplateProp tInfo = new TemplateProp(id.toString(), installPath, objectSummary.getSize(), objectSummary.getSize(), true, false); + TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false); tmpltInfos.put(id, tInfo); } return tmpltInfos; From 04b5f53392965157ffdf1883ddd145c47e896ae3 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 7 Jun 2013 17:55:05 -0700 Subject: [PATCH 281/303] Removed unused code handling for DeleteSnapshotBackupCommand since we don't send that command anymore. --- .../storage/test/MockLocalHostEndPoint.java | 4 +- .../resource/LibvirtComputingResource.java | 31 --------------- .../resource/NfsSecondaryStorageResource.java | 38 ------------------- 3 files changed, 2 insertions(+), 71 deletions(-) diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java index 26c1a634b1e..74caba3a86c 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/MockLocalHostEndPoint.java @@ -20,17 +20,17 @@ package org.apache.cloudstack.storage.test; import org.apache.cloudstack.storage.LocalHostEndpoint; import org.apache.cloudstack.storage.command.CopyCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; public class MockLocalHostEndPoint extends LocalHostEndpoint { @Override public Answer sendMessage(Command cmd) { if ((cmd instanceof CopyCommand) || (cmd instanceof DownloadCommand) - || (cmd instanceof DeleteSnapshotBackupCommand)) { + || (cmd instanceof DeleteCommand)) { return resource.executeRequest(cmd); } // TODO Auto-generated method stub diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index 50187cebd4f..e77b2855182 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -2091,37 +2091,6 @@ ServerResource { + File.separator + snapshotName, true); } - protected DeleteSnapshotBackupAnswer execute( - final DeleteSnapshotBackupCommand cmd) { - Long dcId = cmd.getDataCenterId(); - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); - KVMStoragePool secondaryStoragePool = null; - try { - secondaryStoragePool = _storagePoolMgr.getStoragePoolByURI(cmd - .getSecondaryStorageUrl()); - - String ssPmountPath = secondaryStoragePool.getLocalPath(); - String snapshotDestPath = ssPmountPath + File.separator - + "snapshots" + File.separator + dcId + File.separator - + accountId + File.separator + volumeId; - - final Script command = new Script(_manageSnapshotPath, - _cmdsTimeout, s_logger); - command.add("-d", snapshotDestPath); - command.add("-n", cmd.getSnapshotName()); - - command.execute(); - } catch (CloudRuntimeException e) { - return new DeleteSnapshotBackupAnswer(cmd, false, e.toString()); - } finally { - if (secondaryStoragePool != null) { - _storagePoolMgr.deleteStoragePool(secondaryStoragePool.getType(),secondaryStoragePool.getUuid()); - } - } - return new DeleteSnapshotBackupAnswer(cmd, true, null); - } - protected CreateVolumeFromSnapshotAnswer execute( final CreateVolumeFromSnapshotCommand cmd) { diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index 2fca6c05cbc..be352db432f 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -65,7 +65,6 @@ import com.cloud.agent.api.CheckHealthAnswer; import com.cloud.agent.api.CheckHealthCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DownloadSnapshotFromS3Command; import com.cloud.agent.api.DownloadSnapshotFromSwiftCommand; @@ -197,8 +196,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return execute((DownloadSnapshotFromSwiftCommand) cmd); } else if (cmd instanceof DownloadSnapshotFromS3Command) { return execute((DownloadSnapshotFromS3Command) cmd); - } else if (cmd instanceof DeleteSnapshotBackupCommand) { - return execute((DeleteSnapshotBackupCommand) cmd); } else if (cmd instanceof DeleteSnapshotsDirCommand) { return execute((DeleteSnapshotsDirCommand) cmd); } else if (cmd instanceof DownloadTemplateFromSwiftToSecondaryStorageCommand) { @@ -1284,41 +1281,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - protected Answer execute(final DeleteSnapshotBackupCommand cmd) { - Long accountId = cmd.getAccountId(); - Long volumeId = cmd.getVolumeId(); - String name = cmd.getSnapshotUuid(); - DataStoreTO dstore = cmd.getDataStore(); - if (dstore instanceof NfsTO) { - final String result = deleteSnapshotBackupFromLocalFileSystem(((NfsTO) dstore).getUrl(), accountId, volumeId, name, cmd.isAll()); - if (result != null) { - s_logger.warn(result); - return new Answer(cmd, false, result); - } - } else if (dstore instanceof S3TO) { - final String result = deleteSnapshotBackupfromS3((S3TO) dstore, accountId, volumeId, name, cmd.isAll()); - if (result != null) { - s_logger.warn(result); - return new Answer(cmd, false, result); - } - } else if (dstore instanceof SwiftTO) { - String filename; - if (cmd.isAll()) { - filename = ""; - } else { - filename = name; - } - String result = swiftDelete((SwiftTO) dstore, "V-" + volumeId.toString(), filename); - if (result != null) { - String errMsg = "failed to delete snapshot " + filename + " , err=" + result; - s_logger.warn(errMsg); - return new Answer(cmd, false, errMsg); - } - } else { - return new Answer(cmd, false, "Unsupported image data store: " + dstore); - } - return new Answer(cmd, true, "success"); - } Map swiftListTemplate(SwiftTO swift) { String[] containers = swiftList(swift, "", ""); From cc0de88088784348c3658ed2dbdffe649f8d99b8 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 10 Jun 2013 17:55:30 -0700 Subject: [PATCH 282/303] Remove old DeleteTemplateCommand, DeleteVolumeCommand, DeleteSnapshotBackupCommand, replaced by DeleteCommand. --- .../agent/api/DeleteSnapshotBackupAnswer.java | 32 ------- .../api/DeleteSnapshotBackupCommand.java | 85 ------------------- .../api/storage/DeleteTemplateCommand.java | 62 -------------- .../api/storage/DeleteVolumeCommand.java | 54 ------------ .../storage/to/TemplateObjectTO.java | 13 ++- .../cloudstack/storage/to/VolumeObjectTO.java | 5 ++ .../storage/image/TemplateServiceImpl.java | 12 ++- .../storage/test/DirectAgentTest.java | 2 +- .../storage/volume/VolumeServiceImpl.java | 33 ++++--- .../resource/LibvirtComputingResource.java | 3 - .../agent/manager/MockStorageManager.java | 8 +- .../agent/manager/MockStorageManagerImpl.java | 39 +++------ .../agent/manager/SimulatorManagerImpl.java | 9 +- .../com/cloud/storage/StorageManagerImpl.java | 73 ++-------------- .../cloud/storage/swift/SwiftManagerImpl.java | 13 ++- 15 files changed, 82 insertions(+), 361 deletions(-) delete mode 100644 core/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java delete mode 100644 core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java delete mode 100644 core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java delete mode 100755 core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java deleted file mode 100644 index 9a895d8471a..00000000000 --- a/core/src/com/cloud/agent/api/DeleteSnapshotBackupAnswer.java +++ /dev/null @@ -1,32 +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 com.cloud.agent.api; - - -public class DeleteSnapshotBackupAnswer extends Answer { - - protected DeleteSnapshotBackupAnswer() { - - } - - public DeleteSnapshotBackupAnswer(DeleteSnapshotBackupCommand cmd, boolean success, String details) { - super(cmd, success, details); - } - - - -} diff --git a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java b/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java deleted file mode 100644 index c4f20eae503..00000000000 --- a/core/src/com/cloud/agent/api/DeleteSnapshotBackupCommand.java +++ /dev/null @@ -1,85 +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 com.cloud.agent.api; - -import com.cloud.agent.api.LogLevel.Log4jLevel; -import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.S3TO; -import com.cloud.agent.api.to.SwiftTO; -import com.cloud.storage.StoragePool; - -/** - * This command encapsulates a primitive operation which enables coalescing the backed up VHD snapshots on the secondary server - * This currently assumes that the secondary storage are mounted on the XenServer. - */ -public class DeleteSnapshotBackupCommand extends SnapshotCommand { - @LogLevel(Log4jLevel.Off) - private DataStoreTO store; - private Boolean all; - - public Boolean isAll() { - return all; - } - - public void setAll(Boolean all) { - this.all = all; - } - - public DataStoreTO getDataStore(){ - return store; - } - - protected DeleteSnapshotBackupCommand() { - } - - /** - * Given 2 VHD files on the secondary storage which are linked in a parent chain as follows: - * backupUUID = parent(childUUID) - * It gets another VHD - * previousBackupVHD = parent(backupUUID) - * - * And - * 1) it coalesces backupUuid into its parent. - * 2) It deletes the VHD file corresponding to backupUuid - * 3) It sets the parent VHD of childUUID to that of previousBackupUuid - * - * It takes care of the cases when - * 1) childUUID is null. - Step 3 is not done. - * 2) previousBackupUUID is null - * - Merge childUUID into its parent backupUUID - * - Set the UUID of the resultant VHD to childUUID - * - Essentially we are deleting the oldest VHD file and setting the current oldest VHD to childUUID - * - * @param volumeName The name of the volume whose snapshot was taken (something like i-3-SV-ROOT) - * @param secondaryStoragePoolURL This is what shows up in the UI when you click on Secondary storage. - * In the code, it is present as: In the vmops.host_details table, there is a field mount.parent. This is the value of that field - * If you have better ideas on how to get it, you are welcome. - * @param backupUUID The VHD which has to be deleted - * @param childUUID The child VHD file of the backup whose parent is reset to its grandparent. - */ - public DeleteSnapshotBackupCommand(DataStoreTO store, - String secondaryStoragePoolURL, - Long dcId, - Long accountId, - Long volumeId, - String backupUUID, Boolean all) - { - super(null, secondaryStoragePoolURL, backupUUID, null, dcId, accountId, volumeId); - this.store = store; - setAll(all); - } -} diff --git a/core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java b/core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java deleted file mode 100644 index f72657c5e8a..00000000000 --- a/core/src/com/cloud/agent/api/storage/DeleteTemplateCommand.java +++ /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. -package com.cloud.agent.api.storage; - -import com.cloud.agent.api.to.DataStoreTO; - - -public class DeleteTemplateCommand extends ssCommand { - private DataStoreTO store; - private String templatePath; - private Long templateId; - private Long accountId; - - - public DeleteTemplateCommand() { - } - - - public DeleteTemplateCommand(DataStoreTO store, String templatePath, Long templateId, Long accountId) { - this.templatePath = templatePath; - this.templateId = templateId; - this.accountId = accountId; - this.store = store; - } - - @Override - public boolean executeInSequence() { - return true; - } - - public String getTemplatePath() { - return templatePath; - } - - public Long getTemplateId() { - return templateId; - } - - public Long getAccountId() { - return accountId; - } - - public DataStoreTO getDataStore() { - return store; - } - - -} diff --git a/core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java b/core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java deleted file mode 100755 index 49f0a21967a..00000000000 --- a/core/src/com/cloud/agent/api/storage/DeleteVolumeCommand.java +++ /dev/null @@ -1,54 +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 com.cloud.agent.api.storage; - -import com.cloud.agent.api.to.DataStoreTO; - -public class DeleteVolumeCommand extends ssCommand { - private DataStoreTO store; - private String volumePath; - private Long volumeId; - - public DeleteVolumeCommand() { - } - - public DeleteVolumeCommand(DataStoreTO store, Long volumeId, String volumePath) { - this.store = store; - this.volumeId = volumeId; - this.volumePath = volumePath; - } - - @Override - public boolean executeInSequence() { - return true; - } - - public String getVolumePath() { - return volumePath; - } - - public DataStoreTO getDataStore() { - return store; - } - - public Long getVolumeId() { - return volumeId; - } - - - -} diff --git a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java index 0effd8d567d..b3dc189f26c 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/TemplateObjectTO.java @@ -85,6 +85,10 @@ public class TemplateObjectTO implements DataTO { return id; } + public void setId(long id){ + this.id = id; + } + public ImageFormat getFormat() { return format; } @@ -113,9 +117,6 @@ public class TemplateObjectTO implements DataTO { this.displayText = desc; } - public DataStoreTO getImageDataStore() { - return this.imageDataStore; - } @Override public DataObjectType getObjectType() { @@ -124,7 +125,11 @@ public class TemplateObjectTO implements DataTO { @Override public DataStoreTO getDataStore() { - return (DataStoreTO) this.imageDataStore; + return this.imageDataStore; + } + + public void setDataStore(DataStoreTO store){ + this.imageDataStore = store; } /** diff --git a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java index 549481e0fa6..6057a747a17 100644 --- a/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java +++ b/engine/api/src/org/apache/cloudstack/storage/to/VolumeObjectTO.java @@ -79,6 +79,11 @@ public class VolumeObjectTO implements DataTO { return this.dataStore; } + + public void setDataStore(DataStoreTO store){ + this.dataStore = store; + } + public void setDataStore(PrimaryDataStoreTO dataStore) { this.dataStore = dataStore; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index a0cbc27b1b2..fb8e89c0a2a 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -51,6 +51,7 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; @@ -58,11 +59,11 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.image.store.TemplateObject; +import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; @@ -445,11 +446,14 @@ public class TemplateServiceImpl implements TemplateService { for (String uniqueName : templateInfos.keySet()) { TemplateProp tInfo = templateInfos.get(uniqueName); if (_tmpltMgr.templateIsDeleteable(tInfo.getId())) { - // TODO: we cannot directly call deleteTemplateSync here to + // we cannot directly call deleteTemplateSync here to // reuse delete logic since in this case, our db does not have // this template at all. - DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), tInfo.getInstallPath(), - null, null); + TemplateObjectTO tmplTO = new TemplateObjectTO(); + tmplTO.setDataStore(store.getTO()); + tmplTO.setPath(tInfo.getInstallPath()); + tmplTO.setId(tInfo.getId()); + DeleteCommand dtCommand = new DeleteCommand(tmplTO); EndPoint ep = _epSelector.select(store); Answer answer = ep.sendMessage(dtCommand); if (answer == null || !answer.getResult()) { diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java index d0cfa395d77..b52b1e4fe91 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/DirectAgentTest.java @@ -137,7 +137,7 @@ public class DirectAgentTest extends CloudStackTestNGBase { TemplateObjectTO template = Mockito.mock(TemplateObjectTO.class); Mockito.when(template.getPath()).thenReturn(getTemplateUrl()); - Mockito.when(template.getImageDataStore()).thenReturn(imageStore); + Mockito.when(template.getDataStore()).thenReturn(imageStore); // Mockito.when(image.getTemplate()).thenReturn(template); // CopyTemplateToPrimaryStorageCmd cmd = new diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 04e97dd071d..ed6b86f75cf 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -44,18 +44,20 @@ import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.cloudstack.storage.to.TemplateObjectTO; +import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.to.VirtualMachineTO; @@ -80,7 +82,6 @@ import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.dao.VMInstanceDao; @Component @@ -1127,15 +1128,27 @@ public class VolumeServiceImpl implements VolumeService { } // Delete volumes which are not present on DB. - /* - * for (Long uniqueName : volumeInfos.keySet()) { TemplateProp vInfo = - * volumeInfos.get(uniqueName); - * expungeVolumeAsync(volFactory.getVolume(vInfo.getId(), store)); - * - * String description = "Deleted volume " + vInfo.getTemplateName() + - * " on image store " + storeId; s_logger.info(description); } - */ + for (Long uniqueName : volumeInfos.keySet()) { + TemplateProp tInfo = volumeInfos.get(uniqueName); + //we cannot directly call expungeVolumeAsync here to + // reuse delete logic since in this case, our db does not have + // this template at all. + VolumeObjectTO tmplTO = new VolumeObjectTO(); + tmplTO.setDataStore(store.getTO()); + tmplTO.setPath(tInfo.getInstallPath()); + tmplTO.setId(tInfo.getId()); + DeleteCommand dtCommand = new DeleteCommand(tmplTO); + EndPoint ep = _epSelector.select(store); + Answer answer = ep.sendMessage(dtCommand); + if (answer == null || !answer.getResult()) { + s_logger.info("Failed to deleted volume at store: " + store.getName()); + + } else { + String description = "Deleted volume " + tInfo.getTemplateName() + " on secondary storage " + storeId; + s_logger.info(description); + } + } } private Map listVolume(DataStore store) { diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java index e77b2855182..4f90c440e4d 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -91,9 +91,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteSnapshotBackupAnswer; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; -import com.cloud.agent.api.DeleteSnapshotsDirCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.FenceAnswer; import com.cloud.agent.api.FenceCommand; diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java index 810f33020cf..80a605537df 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManager.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.agent.manager; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; @@ -29,7 +30,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; @@ -42,7 +42,6 @@ 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.DeleteTemplateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ListVolumeCommand; @@ -73,9 +72,10 @@ public interface MockStorageManager extends Manager { public GetStorageStatsAnswer GetStorageStats(GetStorageStatsCommand cmd); public Answer ManageSnapshot(ManageSnapshotCommand cmd); public Answer BackupSnapshot(BackupSnapshotCommand cmd, SimulatorInfo info); - public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd); + //public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd); public Answer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd); - public Answer DeleteTemplate(DeleteTemplateCommand cmd); + //public Answer DeleteTemplate(DeleteTemplateCommand cmd); + public Answer Delete(DeleteCommand cmd); public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd); public void preinstallTemplates(String url, long zoneId); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index a0897b87f22..1fc1d79bbea 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -28,7 +28,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotAnswer; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetStorageStatsAnswer; import com.cloud.agent.api.GetStorageStatsCommand; @@ -45,7 +44,6 @@ 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.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.DownloadAnswer; import com.cloud.agent.api.storage.ListTemplateAnswer; @@ -54,7 +52,9 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; +import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.simulator.MockHost; @@ -80,6 +80,7 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine.State; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; import org.apache.log4j.Logger; @@ -782,28 +783,6 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa return new BackupSnapshotAnswer(cmd, true, null, newsnapshot.getName(), true); } - @Override - public Answer DeleteSnapshotBackup(DeleteSnapshotBackupCommand cmd) { - Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); - try { - txn.start(); - MockVolumeVO backSnapshot = _mockVolumeDao.findByName(cmd.getSnapshotUuid()); - if (backSnapshot == null) { - return new Answer(cmd, false, "can't find the backupsnapshot: " + cmd.getSnapshotUuid()); - } - _mockVolumeDao.remove(backSnapshot.getId()); - txn.commit(); - } catch (Exception ex) { - txn.rollback(); - throw new CloudRuntimeException("Error when deleting snapshot"); - } finally { - txn.close(); - txn = Transaction.open(Transaction.CLOUD_DB); - txn.close(); - } - return new Answer(cmd); - } - @Override public CreateVolumeFromSnapshotAnswer CreateVolumeFromSnapshot(CreateVolumeFromSnapshotCommand cmd) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); @@ -858,20 +837,21 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa return new CreateVolumeFromSnapshotAnswer(cmd, true, null, volume.getPath()); } + @Override - public Answer DeleteTemplate(DeleteTemplateCommand cmd) { + public Answer Delete(DeleteCommand cmd) { Transaction txn = Transaction.open(Transaction.SIMULATOR_DB); try { txn.start(); - MockVolumeVO template = _mockVolumeDao.findByStoragePathAndType(cmd.getTemplatePath()); + MockVolumeVO template = _mockVolumeDao.findByStoragePathAndType(cmd.getData().getPath()); if (template == null) { - return new Answer(cmd, false, "can't find template:" + cmd.getTemplatePath()); + return new Answer(cmd, false, "can't find object to delete:" + cmd.getData().getPath()); } _mockVolumeDao.remove(template.getId()); txn.commit(); } catch (Exception ex) { txn.rollback(); - throw new CloudRuntimeException("Error when deleting template"); + throw new CloudRuntimeException("Error when deleting object"); } finally { txn.close(); txn = Transaction.open(Transaction.CLOUD_DB); @@ -880,6 +860,9 @@ public class MockStorageManagerImpl extends ManagerBase implements MockStorageMa return new Answer(cmd); } + + + @Override public Answer SecStorageVMSetup(SecStorageVMSetupCommand cmd) { return new Answer(cmd); diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java index 081aa5aff7e..5ddf60aebb8 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/SimulatorManagerImpl.java @@ -26,6 +26,7 @@ import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; +import org.apache.cloudstack.storage.command.DeleteCommand; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadProgressCommand; @@ -46,7 +47,6 @@ import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateStoragePoolCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; -import com.cloud.agent.api.DeleteSnapshotBackupCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsCommand; @@ -80,7 +80,6 @@ import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CreateCommand; -import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.agent.api.storage.ListVolumeCommand; @@ -279,12 +278,10 @@ public class SimulatorManagerImpl extends ManagerBase implements SimulatorManage return _mockStorageMgr.ManageSnapshot((ManageSnapshotCommand)cmd); } else if (cmd instanceof BackupSnapshotCommand) { return _mockStorageMgr.BackupSnapshot((BackupSnapshotCommand)cmd, info); - } else if (cmd instanceof DeleteSnapshotBackupCommand) { - return _mockStorageMgr.DeleteSnapshotBackup((DeleteSnapshotBackupCommand)cmd); } else if (cmd instanceof CreateVolumeFromSnapshotCommand) { return _mockStorageMgr.CreateVolumeFromSnapshot((CreateVolumeFromSnapshotCommand)cmd); - } else if (cmd instanceof DeleteTemplateCommand) { - return _mockStorageMgr.DeleteTemplate((DeleteTemplateCommand)cmd); + } else if (cmd instanceof DeleteCommand) { + return _mockStorageMgr.Delete((DeleteCommand)cmd); } else if (cmd instanceof SecStorageVMSetupCommand) { return _mockStorageMgr.SecStorageVMSetup((SecStorageVMSetupCommand)cmd); } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index d5b3f236170..11461794021 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -65,8 +65,10 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; @@ -90,10 +92,7 @@ import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.agent.api.storage.DeleteTemplateCommand; -import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.manager.Commands; -import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; import com.cloud.api.query.dao.TemplateJoinDao; import com.cloud.api.query.vo.TemplateJoinVO; @@ -112,11 +111,8 @@ import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.HostPodDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeploymentPlanner.ExcludeList; -import com.cloud.domain.dao.DomainDao; -import com.cloud.event.dao.EventDao; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConnectionException; import com.cloud.exception.DiscoveryException; @@ -133,39 +129,28 @@ import com.cloud.host.Status; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.HypervisorGuruManager; -import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; import com.cloud.org.Grouping; import com.cloud.org.Grouping.AllocationState; import com.cloud.resource.ResourceState; import com.cloud.server.ManagementServer; import com.cloud.server.StatsCollector; -import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Volume.Type; -import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolWorkDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; -import com.cloud.storage.dao.VMTemplateS3Dao; -import com.cloud.storage.dao.VMTemplateSwiftDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.listener.StoragePoolMonitor; import com.cloud.storage.listener.VolumeStateListener; -import com.cloud.storage.s3.S3Manager; -import com.cloud.storage.secondary.SecondaryStorageVmManager; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.User; import com.cloud.user.UserContext; -import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.UserDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; @@ -184,13 +169,10 @@ import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DiskProfile; -import com.cloud.vm.UserVmManager; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfileImpl; -import com.cloud.vm.dao.ConsoleProxyDao; -import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; @Component @@ -200,8 +182,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C protected String _name; @Inject - protected UserVmManager _userVmMgr; - @Inject protected AgentManager _agentMgr; @Inject protected TemplateManager _tmpltMgr; @@ -214,34 +194,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected HostDao _hostDao; @Inject - protected ConsoleProxyDao _consoleProxyDao; - @Inject protected SnapshotDao _snapshotDao; @Inject - protected SnapshotManager _snapMgr; - @Inject - protected SnapshotPolicyDao _snapshotPolicyDao; - @Inject protected StoragePoolHostDao _storagePoolHostDao; @Inject - protected AlertManager _alertMgr; - @Inject protected VMTemplatePoolDao _vmTemplatePoolDao = null; @Inject protected VMTemplateZoneDao _vmTemplateZoneDao; @Inject - protected VMTemplateSwiftDao _vmTemplateSwiftDao = null; - @Inject - protected VMTemplateS3Dao _vmTemplateS3Dao; - @Inject - protected S3Manager _s3Mgr; - @Inject protected VMTemplateDao _vmTemplateDao = null; @Inject - protected StoragePoolHostDao _poolHostDao = null; - @Inject - protected UserVmDao _userVmDao; - @Inject protected VMInstanceDao _vmInstanceDao; @Inject protected PrimaryDataStoreDao _storagePoolDao = null; @@ -262,22 +224,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected CapacityManager _capacityMgr; @Inject - protected DiskOfferingDao _diskOfferingDao; - @Inject - protected AccountDao _accountDao; - @Inject - protected EventDao _eventDao = null; - @Inject protected DataCenterDao _dcDao = null; @Inject - protected HostPodDao _podDao = null; - @Inject protected VMTemplateDao _templateDao; @Inject - protected ServiceOfferingDao _offeringDao; - @Inject - protected DomainDao _domainDao; - @Inject protected UserDao _userDao; @Inject protected ClusterDao _clusterDao; @@ -288,8 +238,6 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject protected VolumeDao _volumeDao; @Inject - protected SecondaryStorageVmManager _ssvmMgr; - @Inject ConfigurationDao _configDao; @Inject ManagementServer _msServer; @@ -306,13 +254,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C @Inject SnapshotDataFactory snapshotFactory; @Inject - protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao; - @Inject ConfigurationServer _configServer; - - @Inject - protected ResourceTagDao _resourceTagDao; - @Inject DataStoreManager _dataStoreMgr; @Inject @@ -514,7 +456,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C * cmd */ } - List poolHosts = _poolHostDao.listByHostStatus(poolVO.getId(), Status.Up); + List poolHosts = _storagePoolHostDao.listByHostStatus(poolVO.getId(), Status.Up); Collections.shuffle(poolHosts); if (poolHosts != null && poolHosts.size() > 0) { for (StoragePoolHostVO sphvo : poolHosts) { @@ -1153,10 +1095,10 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C } String installPath = destroyedTemplateStoreVO.getInstallPath(); + TemplateInfo tmpl = tmplFactory.getTemplate(destroyedTemplateStoreVO.getTemplateId(), store); if (installPath != null) { EndPoint ep = _epSelector.select(store); - Command cmd = new DeleteTemplateCommand(store.getTO(), destroyedTemplateStoreVO.getInstallPath(), - destroyedTemplate.getId(), destroyedTemplate.getAccountId()); + Command cmd = new DeleteCommand(tmpl.getTO()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { @@ -1230,10 +1172,11 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C String installPath = destroyedStoreVO.getInstallPath(); + VolumeInfo vol = this.volFactory.getVolume(destroyedStoreVO.getVolumeId(), store); + if (installPath != null) { EndPoint ep = _epSelector.select(store); - DeleteVolumeCommand cmd = new DeleteVolumeCommand(store.getTO(), destroyedStoreVO.getVolumeId(), - destroyedStoreVO.getInstallPath()); + DeleteCommand cmd = new DeleteCommand(vol.getTO()); Answer answer = ep.sendMessage(cmd); if (answer == null || !answer.getResult()) { s_logger.debug("Failed to delete " + destroyedStoreVO + " due to " diff --git a/server/src/com/cloud/storage/swift/SwiftManagerImpl.java b/server/src/com/cloud/storage/swift/SwiftManagerImpl.java index 75780b8f158..3149f5aad17 100644 --- a/server/src/com/cloud/storage/swift/SwiftManagerImpl.java +++ b/server/src/com/cloud/storage/swift/SwiftManagerImpl.java @@ -34,9 +34,11 @@ import org.springframework.stereotype.Component; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; -import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.to.SwiftTO; import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.to.TemplateObjectTO; + import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenterVO; @@ -144,7 +146,10 @@ public class SwiftManagerImpl extends ManagerBase implements SwiftManager { s_logger.warn(msg); throw new CloudRuntimeException(msg); } - Answer answer = _agentMgr.sendToSSVM(null, new DeleteTemplateCommand(swift, null, cmd.getId(), null)); + TemplateObjectTO tmplTO = new TemplateObjectTO(); + tmplTO.setDataStore(swift); + tmplTO.setId(cmd.getId()); + Answer answer = _agentMgr.sendToSSVM(null, new DeleteCommand(tmplTO)); if (answer == null || !answer.getResult()) { msg = "Failed to delete " + tmpltSwiftRef + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()); s_logger.warn(msg); @@ -170,7 +175,9 @@ public class SwiftManagerImpl extends ManagerBase implements SwiftManager { s_logger.warn(msg); throw new CloudRuntimeException(msg); } - Answer answer = _agentMgr.sendToSSVM(null, new DeleteTemplateCommand(swift, null, cmd.getId(), null)); + TemplateObjectTO tmplTO = new TemplateObjectTO(); + tmplTO.setId(cmd.getId()); + Answer answer = _agentMgr.sendToSSVM(null, new DeleteCommand(tmplTO)); if (answer == null || !answer.getResult()) { msg = "Failed to delete " + tmpltSwiftRef + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()); s_logger.warn(msg); From 3bf15bd1ff8a852efea73a37b7a8607dc791cb79 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 10 Jun 2013 18:03:15 -0700 Subject: [PATCH 283/303] Code cleanup. --- .../storage/image/TemplateServiceImpl.java | 15 --------------- .../storage/volume/VolumeServiceImpl.java | 10 ---------- .../agent/manager/MockStorageManagerImpl.java | 2 -- 3 files changed, 27 deletions(-) diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index fb8e89c0a2a..9b6382b80b7 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -56,7 +56,6 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.to.TemplateObjectTO; @@ -67,7 +66,6 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ListTemplateAnswer; import com.cloud.agent.api.storage.ListTemplateCommand; import com.cloud.alert.AlertManager; -import com.cloud.api.query.dao.UserVmJoinDao; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.ClusterDao; import com.cloud.dc.dao.DataCenterDao; @@ -81,8 +79,6 @@ import com.cloud.storage.VMTemplateZoneVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.template.TemplateConstants; import com.cloud.storage.template.TemplateProp; import com.cloud.template.TemplateManager; @@ -90,7 +86,6 @@ import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.UriUtils; import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.vm.dao.UserVmDao; @Component public class TemplateServiceImpl implements TemplateService { @@ -114,22 +109,12 @@ public class TemplateServiceImpl implements TemplateService { @Inject TemplateDataStoreDao _vmTemplateStoreDao; @Inject - VolumeDataStoreDao _volumeStoreDao; - @Inject - DownloadMonitor _dlMonitor; - @Inject DataCenterDao _dcDao = null; @Inject VMTemplateZoneDao _vmTemplateZoneDao; @Inject ClusterDao _clusterDao; @Inject - UserVmDao _userVmDao; - @Inject - UserVmJoinDao _userVmJoinDao; - @Inject - VolumeDao _volumeDao; - @Inject TemplateDataFactory _templateFactory; @Inject VMTemplatePoolDao _tmpltPoolDao; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index ed6b86f75cf..7d5b7a2937c 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -51,12 +51,10 @@ import org.apache.cloudstack.storage.datastore.PrimaryDataStore; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; -import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; @@ -75,14 +73,12 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.template.TemplateProp; import com.cloud.user.AccountManager; import com.cloud.user.ResourceLimitService; import com.cloud.utils.NumbersUtil; import com.cloud.utils.db.DB; -import com.cloud.vm.dao.VMInstanceDao; @Component public class VolumeServiceImpl implements VolumeService { @@ -104,18 +100,12 @@ public class VolumeServiceImpl implements VolumeService { @Inject ResourceLimitService _resourceLimitMgr; @Inject - DownloadMonitor downloadMonitor; - @Inject AccountManager _accountMgr; @Inject AlertManager _alertMgr; @Inject - VMInstanceDao vmDao; - @Inject ConfigurationDao configDao; @Inject - AgentManager _agentMgr; - @Inject VolumeDataStoreDao _volumeStoreDao; @Inject VolumeDao _volumeDao; diff --git a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java index 1fc1d79bbea..21b81e1d7bb 100644 --- a/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java +++ b/plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockStorageManagerImpl.java @@ -52,9 +52,7 @@ import com.cloud.agent.api.storage.ListVolumeAnswer; import com.cloud.agent.api.storage.ListVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; -import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.StorageFilerTO; import com.cloud.agent.api.to.VolumeTO; import com.cloud.simulator.MockHost; From ec55c2e909790c2320a3b5658b7031a5fe0416f7 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 11 Jun 2013 17:07:26 -0700 Subject: [PATCH 284/303] CS-17842: java.lang.NullPointerException seen when using "updateTemplatePermission" with projectids parameter. --- server/src/com/cloud/template/TemplateManagerImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index b39936f4ffc..c15bd6b4b7f 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1199,6 +1199,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, // convert projectIds to accountNames if (projectIds != null) { + // CS-17842, initialize accountNames list + if (accountNames == null ){ + accountNames = new ArrayList(); + } for (Long projectId : projectIds) { Project project = _projectMgr.getProject(projectId); if (project == null) { From 1b905463c8697f1c0552c288ee136cd2316a8f2a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 12 Jun 2013 13:54:56 -0700 Subject: [PATCH 285/303] Fix vmware plugin unit testcase failure. --- .../cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java index de08c93c78a..d79d41e024c 100644 --- a/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java +++ b/plugins/hypervisors/vmware/test/com/cloud/hypervisor/vmware/VmwareDatacenterApiUnitTest.java @@ -32,6 +32,7 @@ import junit.framework.TestCase; import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd; import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; import org.apache.cloudstack.test.utils.SpringUtils; import org.junit.Before; import org.junit.BeforeClass; @@ -414,6 +415,10 @@ public class VmwareDatacenterApiUnitTest { return Mockito.mock(RemoveVmwareDcCmd.class); } + @Bean + public DataStoreManager dataStoreManager() { + return Mockito.mock(DataStoreManager.class); + } public static class Library implements TypeFilter { @Override From 80ed9254b625f663a0631c4a18902476e3736313 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 12 Jun 2013 15:37:21 -0700 Subject: [PATCH 286/303] Fix db creation issue caused from merge conflict. --- engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 19194861817..8739ac97a02 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -312,6 +312,7 @@ public class Upgrade410to420 implements DbUpgrade { } catch (SQLException e) { } } + /* pstmt = null; try { pstmt = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'"); @@ -326,6 +327,7 @@ public class Upgrade410to420 implements DbUpgrade { } } } + */ } From 6e0757bbf50951988c8b5ad50391f8fcff5d1c63 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 12 Jun 2013 15:52:43 -0700 Subject: [PATCH 287/303] Fix indentation error in deployDataCenter.py. --- tools/marvin/marvin/deployDataCenter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py index b42d79d9fa5..66b3e322890 100644 --- a/tools/marvin/marvin/deployDataCenter.py +++ b/tools/marvin/marvin/deployDataCenter.py @@ -321,7 +321,7 @@ class deployDataCenters(): createzone.localstorageenabled = zone.localstorageenabled createzone.networktype = zone.networktype if zone.securitygroupenabled != "true": - createzone.guestcidraddress = zone.guestcidraddress + createzone.guestcidraddress = zone.guestcidraddress zoneresponse = self.apiClient.createZone(createzone) zoneId = zoneresponse.id From 7a3e7d1891fd2da730a4decda6e130c596f1e65a Mon Sep 17 00:00:00 2001 From: Min Chen Date: Thu, 13 Jun 2013 11:21:25 -0700 Subject: [PATCH 288/303] Send CopyCommand to Host instead of randomly picking host and ssvm in backup snapshot. For VMware, it will delegate to ssvm in VMwareGuru. --- .../cloudstack/storage/endpoint/DefaultEndPointSelector.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java index 53a8724e60a..a44bbec635a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java +++ b/engine/storage/src/org/apache/cloudstack/storage/endpoint/DefaultEndPointSelector.java @@ -55,8 +55,6 @@ public class DefaultEndPointSelector implements EndPointSelector { private static final Logger s_logger = Logger.getLogger(DefaultEndPointSelector.class); @Inject HostDao hostDao; - private String findOneHostInaScope = "select id from host where " - + " status = 'Up' and type in ('Routing', 'SecondaryStorageVM') "; private String findOneHostOnPrimaryStorage = "select id from host where " + "status = 'Up' and type = 'Routing' "; protected boolean moveBetweenPrimaryImage(DataStore srcStore, DataStore destStore) { @@ -158,7 +156,7 @@ public class DefaultEndPointSelector implements EndPointSelector { // if both are zone scope selectedScope = srcScope; } - return findEndPointInScope(selectedScope, findOneHostInaScope); + return findEndPointInScope(selectedScope, findOneHostOnPrimaryStorage); } @Override From c5083a385f95907ac3a45ab6a760fbc304d8c621 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 14 Jun 2013 10:54:41 -0700 Subject: [PATCH 289/303] Migrate NFS secondary storage data from 4.1 to 4.2. --- .../cloud/upgrade/dao/Upgrade410to420.java | 311 +++++++++++++++++- 1 file changed, 310 insertions(+), 1 deletion(-) diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 8739ac97a02..521ddd3de89 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -18,9 +18,11 @@ package com.cloud.upgrade.dao; import com.cloud.deploy.DeploymentPlanner; -import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.script.Script; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProvider; import org.apache.log4j.Logger; import java.io.File; import java.sql.Connection; @@ -30,13 +32,20 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.UUID; import com.cloud.network.vpc.NetworkACL; public class Upgrade410to420 implements DbUpgrade { final static Logger s_logger = Logger.getLogger(Upgrade410to420.class); +// private Map host_store_id_map = new HashMap(); +// private Map s3_store_id_map = new HashMap(); +// private Map swift_store_id_map = new HashMap(); + @Override public String[] getUpgradableVersionRange() { return new String[] { "4.1.0", "4.2.0" }; @@ -83,6 +92,12 @@ public class Upgrade410to420 implements DbUpgrade { removeFirewallServiceFromSharedNetworkOfferingWithSGService(conn); fix22xKVMSnapshots(conn); addIndexForAlert(conn); + // storage refactor related migration + // TODO: add clean-up scripts to delete the deprecated table. + migrateSecondaryStorageToImageStore(conn); + migrateVolumeHostRef(conn); + migrateTemplateHostRef(conn); + migrateSnapshotStoreRef(conn); } private void addIndexForAlert(Connection conn) { @@ -1587,4 +1602,298 @@ public class Upgrade410to420 implements DbUpgrade { s_logger.info("Successfully upgraded network using F5 and SRX devices to have a entry in the network_external_lb_device_map and network_external_firewall_device_map"); } } + + // migrate secondary storages (NFS, S3, Swift) from host, s3, swift tables to image_store table + private void migrateSecondaryStorageToImageStore(Connection conn) { + PreparedStatement storeInsert = null; + PreparedStatement storeDetailInsert = null; + PreparedStatement storeQuery = null; + PreparedStatement s3Query = null; + PreparedStatement swiftQuery = null; + PreparedStatement nfsQuery = null; + ResultSet rs = null; + ResultSet storeInfo = null; + Long storeId = null; + + + try { + storeQuery = conn.prepareStatement("select id from `cloud`.`image_store` where uuid = ?"); + storeDetailInsert = conn + .prepareStatement("INSERT INTO `cloud`.`image_store_details` (store_id, name, value) values(?, ?, ?)"); + + /* + // migrate S3 secondary storage + storeInsert = conn + .prepareStatement("INSERT INTO `cloud`.`image_store` (uuid, name, image_provider_name, protocol, scope, role, created) values(?, ?, 'S3', ?, 'REGION', 'Image', ?)"); + s3Query = conn + .prepareStatement("select id, uuid, access_key, secret_key, end_point, bucket, https, connection_timeout, max_error_retry, socket_timeout, created from `cloud`.`s3`"); + rs = s3Query.executeQuery(); + + while (rs.next()) { + Long s3_id = rs.getLong("id"); + String s3_uuid = rs.getString("uuid"); + String s3_accesskey = rs.getString("access_key"); + String s3_secretkey = rs.getString("secret_key"); + String s3_endpoint = rs.getString("end_point"); + String s3_bucket = rs.getString("bucket"); + boolean s3_https = rs.getObject("https") != null ? (rs.getInt("https") == 0 ? false : true) : false; + Integer s3_connectiontimeout = rs.getObject("connection_timeout") != null ? rs + .getInt("connection_timeout") : null; + Integer s3_retry = rs.getObject("max_error_retry") != null ? rs.getInt("max_error_retry") : null; + Integer s3_sockettimeout = rs.getObject("socket_timeout") != null ? rs.getInt("socket_timeout") : null; + Date s3_created = rs.getDate("created"); + + // insert entry in image_store table and image_store_details + // table and store s3_id and store_id mapping + + storeInsert.setString(1, s3_uuid); + storeInsert.setString(2, s3_uuid); + storeInsert.setString(3, s3_https ? "https" : "http"); + storeInsert.setDate(4, s3_created); + storeInsert.executeUpdate(); + + storeQuery.setString(1, s3_uuid); + storeInfo = storeQuery.executeQuery(); + if (storeInfo.next()) { + storeId = storeInfo.getLong("id"); + } + + Map detailMap = new HashMap(); + detailMap.put(ApiConstants.S3_ACCESS_KEY, s3_accesskey); + detailMap.put(ApiConstants.S3_SECRET_KEY, s3_secretkey); + detailMap.put(ApiConstants.S3_BUCKET_NAME, s3_bucket); + detailMap.put(ApiConstants.S3_END_POINT, s3_endpoint); + detailMap.put(ApiConstants.S3_HTTPS_FLAG, String.valueOf(s3_https)); + if (s3_connectiontimeout != null) { + detailMap.put(ApiConstants.S3_CONNECTION_TIMEOUT, String.valueOf(s3_connectiontimeout)); + } + if (s3_retry != null) { + detailMap.put(ApiConstants.S3_MAX_ERROR_RETRY, String.valueOf(s3_retry)); + } + if (s3_sockettimeout != null) { + detailMap.put(ApiConstants.S3_SOCKET_TIMEOUT, String.valueOf(s3_sockettimeout)); + } + + Iterator keyIt = detailMap.keySet().iterator(); + while (keyIt.hasNext()) { + String key = keyIt.next(); + String val = detailMap.get(key); + storeDetailInsert.setLong(1, storeId); + storeDetailInsert.setString(2, key); + storeDetailInsert.setString(3, val); + storeDetailInsert.executeUpdate(); + } + s3_store_id_map.put(s3_id, storeId); + } + + // migrate SWIFT secondary storage + storeInsert = conn + .prepareStatement("INSERT INTO `cloud`.`image_store` (uuid, name, image_provider_name, protocol, url, scope, role, created) values(?, ?, 'Swift', 'http', ?, 'REGION', 'Image', ?)"); + swiftQuery = conn + .prepareStatement("select id, uuid, url, account, username, key, created from `cloud`.`swift`"); + rs = swiftQuery.executeQuery(); + + while (rs.next()) { + Long swift_id = rs.getLong("id"); + String swift_uuid = rs.getString("uuid"); + String swift_url = rs.getString("url"); + String swift_account = rs.getString("account"); + String swift_username = rs.getString("username"); + String swift_key = rs.getString("key"); + Date swift_created = rs.getDate("created"); + + // insert entry in image_store table and image_store_details + // table and store swift_id and store_id mapping + storeInsert.setString(1, swift_uuid); + storeInsert.setString(2, swift_uuid); + storeInsert.setString(3, swift_url); + storeInsert.setDate(4, swift_created); + storeInsert.executeUpdate(); + + storeQuery.setString(1, swift_uuid); + storeInfo = storeQuery.executeQuery(); + if (storeInfo.next()) { + storeId = storeInfo.getLong("id"); + } + + Map detailMap = new HashMap(); + detailMap.put(ApiConstants.ACCOUNT, swift_account); + detailMap.put(ApiConstants.USERNAME, swift_username); + detailMap.put(ApiConstants.KEY, swift_key); + + Iterator keyIt = detailMap.keySet().iterator(); + while (keyIt.hasNext()) { + String key = keyIt.next(); + String val = detailMap.get(key); + storeDetailInsert.setLong(1, storeId); + storeDetailInsert.setString(2, key); + storeDetailInsert.setString(3, val); + storeDetailInsert.executeUpdate(); + } + swift_store_id_map.put(swift_id, storeId); + } + */ + + // migrate NFS secondary storage, for nfs, keep previous host_id as the store_id + storeInsert = conn + .prepareStatement("INSERT INTO `cloud`.`image_store` (id, uuid, name, image_provider_name, protocol, url, data_center_id, scope, role, parent, total_size, created) values(?, ?, ?, 'NFS', 'nfs', ?, ?, 'ZONE', 'Image', ?, ?, ?)"); + nfsQuery = conn + .prepareStatement("select id, uuid, url, data_center_id, parent, total_size, created from `cloud`.`host` where type = 'SecondaryStorage' and removed is null"); + rs = nfsQuery.executeQuery(); + + while (rs.next()) { + Long nfs_id = rs.getLong("id"); + String nfs_uuid = rs.getString("uuid"); + String nfs_url = rs.getString("url"); + String nfs_parent = rs.getString("parent"); + int nfs_dcid = rs.getInt("data_center_id"); + Long nfs_totalsize = rs.getObject("total_size") != null ? rs.getLong("total_size") : null; + Date nfs_created = rs.getDate("created"); + + // insert entry in image_store table and image_store_details + // table and store host_id and store_id mapping + storeInsert.setLong(1, nfs_id); + storeInsert.setString(2, nfs_uuid); + storeInsert.setString(3, nfs_uuid); + storeInsert.setString(4, nfs_url); + storeInsert.setInt(5, nfs_dcid); + storeInsert.setString(6, nfs_parent); + if (nfs_totalsize != null){ + storeInsert.setLong(7, nfs_totalsize); + } + else{ + storeInsert.setNull(7, Types.BIGINT); + } + storeInsert.setDate(8, nfs_created); + storeInsert.executeUpdate(); + + storeQuery.setString(1, nfs_uuid); + storeInfo = storeQuery.executeQuery(); + if (storeInfo.next()) { + storeId = storeInfo.getLong("id"); + } + + //host_store_id_map.put(nfs_id, storeId); + } + } + catch (SQLException e) { + String msg = "Unable to migrate secondary storages." + e.getMessage(); + s_logger.error(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (storeInfo != null) { + storeInfo.close(); + } + + if (storeInsert != null) { + storeInsert.close(); + } + if (storeDetailInsert != null) { + storeDetailInsert.close(); + } + if (storeQuery != null) { + storeQuery.close(); + } + if (swiftQuery != null) { + swiftQuery.close(); + } + if (s3Query != null) { + s3Query.close(); + } + if (nfsQuery != null) { + nfsQuery.close(); + } + } catch (SQLException e) { + } + } + } + + // migrate volume_host_ref to volume_store_ref + private void migrateVolumeHostRef(Connection conn) { + PreparedStatement volStoreInsert = null; + PreparedStatement volStoreUpdate = null; + + try { + + volStoreInsert = conn + .prepareStatement("INSERT INTO `cloud`.`volume_store_ref` (store_id, volume_id, zone_id, created, last_updated, job_id, download_pct, size, physical_size, download_state, checksum, error_str, local_path, install_path, url, destroyed, state) select host_id, volume_id, zone_id, created, last_updated, job_id, download_pct, size, physical_size, download_state, checksum, error_str, local_path, install_path, url, destroyed, 'Allocated' from `cloud`.`volume_host_ref`"); + volStoreInsert.executeUpdate(); + + volStoreUpdate = conn.prepareStatement("update `cloud`.`volume_store_ref` set state = 'Ready' where download_state = 'DOWNLOADED'"); + volStoreUpdate.executeUpdate(); + } + catch (SQLException e) { + String msg = "Unable to migrate volume_host_ref." + e.getMessage(); + s_logger.error(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try{ + if (volStoreInsert != null) { + volStoreInsert.close(); + } + if (volStoreUpdate != null) { + volStoreUpdate.close(); + } + } catch (SQLException e) { + } + } + } + + // migrate template_host_ref to template_store_ref + private void migrateTemplateHostRef(Connection conn) { + PreparedStatement tmplStoreInsert = null; + PreparedStatement tmplStoreUpdate = null; + + try { + + tmplStoreInsert = conn + .prepareStatement("INSERT INTO `cloud`.`template_store_ref` (store_id, template_id, created, last_updated, job_id, download_pct, size, physical_size, download_state, error_str, local_path, install_path, url, destroyed, is_copy, store_role, state) select host_id, template_id, created, last_updated, job_id, download_pct, size, physical_size, download_state, error_str, local_path, install_path, url, destroyed, is_copy, 'Image', 'Allocated' from `cloud`.`template_host_ref`"); + tmplStoreInsert.executeUpdate(); + + tmplStoreUpdate = conn.prepareStatement("update `cloud`.`template_store_ref` set state = 'Ready' where download_state = 'DOWNLOADED'"); + tmplStoreUpdate.executeUpdate(); + } + catch (SQLException e) { + String msg = "Unable to migrate template_host_ref." + e.getMessage(); + s_logger.error(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try{ + if (tmplStoreInsert != null) { + tmplStoreInsert.close(); + } + if (tmplStoreUpdate != null) { + tmplStoreUpdate.close(); + } + } catch (SQLException e) { + } + } + } + + // migrate some entry contents of snapshots to snapshot_store_ref + private void migrateSnapshotStoreRef(Connection conn) { + PreparedStatement snapshotStoreInsert = null; + + try { + snapshotStoreInsert = conn + .prepareStatement("INSERT INTO `cloud`.`snapshot_store_ref` (store_id, snapshot_id, created, size, parent_snapshot_id, install_path, state) select sechost_id, id, created, size, prev_snap_id, path, 'Ready' from `cloud`.`snapshots` where status = 'BackedUp' and sechost_id is not null and removed is null"); + snapshotStoreInsert.executeUpdate(); + } + catch (SQLException e) { + String msg = "Unable to migrate snapshot_store_ref." + e.getMessage(); + s_logger.error(msg); + throw new CloudRuntimeException(msg, e); + } finally { + try{ + if (snapshotStoreInsert != null) { + snapshotStoreInsert.close(); + } + } catch (SQLException e) { + } + } + } } From bb85a564dabe82dfbe16b80ee7e9cc74cbc000ee Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 14 Jun 2013 15:14:09 -0700 Subject: [PATCH 290/303] Remove state from vm_template table, we should use template_store_ref state column to represent the state of a template in each zone. --- client/tomcatconf/applicationContext.xml.in | 1 - .../src/com/cloud/storage/VMTemplateVO.java | 14 +- .../com/cloud/storage/dao/VMTemplateDao.java | 3 +- .../cloud/storage/dao/VMTemplateDaoImpl.java | 179 +++++++----------- .../storage/image/TemplateServiceImpl.java | 39 +--- .../image/manager/ImageDataManager.java | 30 --- .../image/manager/ImageDataManagerImpl.java | 52 ----- .../storage/image/store/TemplateObject.java | 27 ++- .../api/query/dao/TemplateJoinDaoImpl.java | 11 +- .../cloud/api/query/vo/TemplateJoinVO.java | 26 +-- setup/db/db/schema-410to420.sql | 5 +- 11 files changed, 108 insertions(+), 279 deletions(-) delete mode 100644 engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java delete mode 100644 engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 01936421d50..8d251eed66f 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -764,7 +764,6 @@ - diff --git a/engine/schema/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java index 00c394fa1fa..ac5f0210d7a 100755 --- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java +++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java @@ -42,7 +42,7 @@ import com.cloud.utils.fsm.StateObject; @Entity @Table(name = "vm_template") -public class VMTemplateVO implements VirtualMachineTemplate, StateObject { +public class VMTemplateVO implements VirtualMachineTemplate { @Id @TableGenerator(name = "vm_template_sq", table = "sequence", pkColumnName = "name", valueColumnName = "value", pkColumnValue = "vm_template_seq", allocationSize = 1) @@ -133,9 +133,6 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject, - StateDao { +public interface VMTemplateDao extends GenericDao { public List listByPublic(); diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java index 21dd0adce4e..e7b85f8a63f 100755 --- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java @@ -102,7 +102,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem private SearchBuilder PublicIsoSearch; private SearchBuilder UserIsoSearch; private GenericSearchBuilder CountTemplatesByAccount; - private SearchBuilder updateStateSearch; + // private SearchBuilder updateStateSearch; @Inject ResourceTagDao _tagsDao; @@ -369,11 +369,11 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem CountTemplatesByAccount.and("removed", CountTemplatesByAccount.entity().getRemoved(), SearchCriteria.Op.NULL); CountTemplatesByAccount.done(); - updateStateSearch = this.createSearchBuilder(); - updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); - updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); - updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); - updateStateSearch.done(); +// updateStateSearch = this.createSearchBuilder(); +// updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ); +// updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ); +// updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ); +// updateStateSearch.done(); return result; } @@ -390,25 +390,25 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * pageSize, Long startIndex, Long zoneId, HypervisorType hyperType, boolean * onlyReady, boolean showDomr, List permittedAccounts, Account * caller, Map tags) { - * + * * StringBuilder builder = new StringBuilder(); if * (!permittedAccounts.isEmpty()) { for (Account permittedAccount : * permittedAccounts) { builder.append(permittedAccount.getAccountId() + * ","); } } - * + * * String permittedAccountsStr = builder.toString(); - * + * * if (permittedAccountsStr.length() > 0) { // chop the "," off * permittedAccountsStr = permittedAccountsStr.substring(0, * permittedAccountsStr.length() - 1); } - * + * * Transaction txn = Transaction.currentTxn(); txn.start(); - * + * * Set> templateZonePairList = new HashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; String sql * = SELECT_TEMPLATE_SWIFT_REF; try { String joinClause = ""; String * whereClause = " WHERE t.removed IS NULL"; - * + * * if (isIso) { whereClause += " AND t.format = 'ISO'"; if * (!hyperType.equals(HypervisorType.None)) { joinClause = * " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) " @@ -424,12 +424,12 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * (keyword != null) { whereClause += " AND t.name LIKE \"%" + keyword + * "%\""; } else if (name != null) { whereClause += " AND t.name LIKE \"%" + * name + "%\""; } - * + * * if (bootable != null) { whereClause += " AND t.bootable = " + bootable; } - * + * * if (!showDomr) { whereClause += " AND t.type != '" + * Storage.TemplateType.SYSTEM.toString() + "'"; } - * + * * if (templateFilter == TemplateFilter.featured) { whereClause += * " AND t.public = 1 AND t.featured = 1"; } else if ((templateFilter == * TemplateFilter.self || templateFilter == TemplateFilter.selfexecutable) @@ -455,20 +455,20 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * TemplateFilter.all && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { } * else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { return * templateZonePairList; } - * + * * sql += joinClause + whereClause + getOrderByLimit(pageSize, startIndex); * pstmt = txn.prepareStatement(sql); rs = pstmt.executeQuery(); while * (rs.next()) { Pair templateZonePair = new Pair(rs.getLong(1), -1L); templateZonePairList.add(templateZonePair); } - * + * * } catch (Exception e) { s_logger.warn("Error listing templates", e); } * finally { try { if (rs != null) { rs.close(); } if (pstmt != null) { * pstmt.close(); } txn.commit(); } catch (SQLException sqle) { * s_logger.warn("Error in cleaning up", sqle); } } - * + * * return templateZonePairList; } - * - * + * + * * @Override public Set> searchTemplates(String name, * String keyword, TemplateFilter templateFilter, boolean isIso, * List hypers, Boolean bootable, DomainVO domain, Long @@ -479,15 +479,15 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * StringBuilder(); if (!permittedAccounts.isEmpty()) { for (Account * permittedAccount : permittedAccounts) { * builder.append(permittedAccount.getAccountId() + ","); } } - * + * * String permittedAccountsStr = builder.toString(); - * + * * if (permittedAccountsStr.length() > 0) { //chop the "," off * permittedAccountsStr = permittedAccountsStr.substring(0, * permittedAccountsStr.length()-1); } - * + * * Transaction txn = Transaction.currentTxn(); txn.start(); - * + * * // Use LinkedHashSet here to guarantee iteration order Set> templateZonePairList = new LinkedHashSet>(); * PreparedStatement pstmt = null; ResultSet rs = null; StringBuilder @@ -496,7 +496,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * accountType; //String accountId = null; String guestOSJoin = ""; * StringBuilder templateHostRefJoin = new StringBuilder(); String * dataCenterJoin = "", lpjoin = ""; String tagsJoin = ""; - * + * * if (isIso && !hyperType.equals(HypervisorType.None)) { guestOSJoin = * " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) " * ; } if (onlyReady){ templateHostRefJoin.append( @@ -506,22 +506,22 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * TemplateFilter.featured) || (templateFilter == TemplateFilter.community)) * { dataCenterJoin = * " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - * + * * if (zoneType != null) { dataCenterJoin = * " INNER JOIN template_host_ref thr on (t.id = thr.template_id) INNER JOIN host h on (thr.host_id = h.id)" * ; dataCenterJoin += * " INNER JOIN data_center dc on (h.data_center_id = dc.id)"; } - * + * * if (templateFilter == TemplateFilter.sharedexecutable || templateFilter * == TemplateFilter.shared ){ lpjoin = * " INNER JOIN launch_permission lp ON t.id = lp.template_id "; } - * + * * if (tags != null && !tags.isEmpty()) { tagsJoin = * " INNER JOIN resource_tags r ON t.id = r.resource_id "; } - * + * * sql += guestOSJoin + templateHostRefJoin + dataCenterJoin + lpjoin + * tagsJoin; String whereClause = ""; - * + * * //All joins have to be made before we start setting the condition * settings if ((listProjectResourcesCriteria == * ListProjectResourcesCriteria.SkipProjectResources || @@ -541,19 +541,19 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * (listProjectResourcesCriteria == * ListProjectResourcesCriteria.SkipProjectResources) { whereClause += * " WHERE a.type != " + Account.ACCOUNT_TYPE_PROJECT; } } - * + * * if (!permittedAccounts.isEmpty()) { for (Account account : * permittedAccounts) { //accountType = account.getType(); //accountId = * Long.toString(account.getId()); DomainVO accountDomain = * _domainDao.findById(account.getDomainId()); - * + * * // get all parent domain ID's all the way till root domain DomainVO * domainTreeNode = accountDomain; while (true) { * relatedDomainIds.append(domainTreeNode.getId()); * relatedDomainIds.append(","); if (domainTreeNode.getParent() != null) { * domainTreeNode = _domainDao.findById(domainTreeNode.getParent()); } else * { break; } } - * + * * // get all child domain ID's if (isAdmin(account.getType()) ) { * List allChildDomains = * _domainDao.findAllChildren(accountDomain.getPath(), @@ -561,10 +561,10 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * relatedDomainIds.append(childDomain.getId()); * relatedDomainIds.append(","); } } * relatedDomainIds.setLength(relatedDomainIds.length()-1); } } - * + * * String attr = " AND "; if (whereClause.endsWith(" WHERE ")) { attr += * " WHERE "; } - * + * * if (!isIso) { if ( hypers.isEmpty() ) { return templateZonePairList; } * else { StringBuilder relatedHypers = new StringBuilder(); for * (HypervisorType hyper : hypers ) { relatedHypers.append("'"); @@ -572,14 +572,14 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * relatedHypers.append(","); } * relatedHypers.setLength(relatedHypers.length()-1); whereClause += attr + * " t.hypervisor_type IN (" + relatedHypers + ")"; } } - * + * * if (!permittedAccounts.isEmpty() && !(templateFilter == * TemplateFilter.featured || templateFilter == TemplateFilter.community || * templateFilter == TemplateFilter.executable || templateFilter == * TemplateFilter.shared || templateFilter == * TemplateFilter.sharedexecutable) && !isAdmin(caller.getType()) ) { * whereClause += attr + "t.account_id IN (" + permittedAccountsStr + ")"; } - * + * * if (templateFilter == TemplateFilter.featured) { whereClause += attr + * "t.public = 1 AND t.featured = 1"; if (!permittedAccounts.isEmpty()) { * whereClause += attr + "(dc.domain_id IN (" + relatedDomainIds + @@ -599,22 +599,22 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * "(dc.domain_id IN (" + relatedDomainIds + ") OR dc.domain_id is NULL)"; } * } else if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN && !isIso) { * return templateZonePairList; } - * + * * if (tags != null && !tags.isEmpty()) { whereClause += " AND ("; boolean * first = true; for (String key : tags.keySet()) { if (!first) { * whereClause += " OR "; } whereClause += "(r.key=\"" + key + * "\" and r.value=\"" + tags.get(key) + "\")"; first = false; } whereClause * += ")"; } - * + * * if (whereClause.equals("")) { whereClause += " WHERE "; } else if * (!whereClause.equals(" WHERE ")) { whereClause += " AND "; } - * + * * sql += whereClause + getExtrasWhere(templateFilter, name, keyword, isIso, * bootable, hyperType, zoneId, onlyReady, showDomr, zoneType) + * groupByClause + getOrderByLimit(pageSize, startIndex); - * + * * pstmt = txn.prepareStatement(sql); rs = pstmt.executeQuery(); - * + * * while (rs.next()) { Pair templateZonePair = new Pair(rs.getLong(1), rs.getLong(2)); * templateZonePairList.add(templateZonePair); } //for now, defaulting @@ -623,18 +623,18 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * templateFilter != TemplateFilter.community && !(templateFilter == * TemplateFilter.self && !BaseCmd.isRootAdmin(caller.getType())) ){ * //evaluates to true If root admin and filter=self - * + * * List publicIsos = publicIsoSearch(bootable, false, tags); * List userIsos = userIsoSearch(false); - * + * * //Listing the ISOs according to the page size.Restricting the total no. * of ISOs on a page //to be less than or equal to the pageSize parameter - * + * * int i=0; - * + * * if (startIndex > userIsos.size()) { i=(int) (startIndex - * userIsos.size()); } - * + * * for (; i < publicIsos.size(); i++) { if(templateZonePairList.size() >= * pageSize){ break; } else { if (keyword != null && * publicIsos.get(i).getName().contains(keyword)) { @@ -649,7 +649,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * null) { rs.close(); } if (pstmt != null) { pstmt.close(); } txn.commit(); * } catch( SQLException sqle) { s_logger.warn("Error in cleaning up", * sqle); } } - * + * * return templateZonePairList; } */ @@ -660,39 +660,39 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * zoneType) { String sql = ""; if (keyword != null) { sql += * " t.name LIKE \"%" + keyword + "%\" AND"; } else if (name != null) { sql * += " t.name LIKE \"%" + name + "%\" AND"; } - * + * * if (isIso) { sql += " t.format = 'ISO'"; if * (!hyperType.equals(HypervisorType.None)) { sql += * " AND goh.hypervisor_type = '" + hyperType.toString() + "'"; } } else { * sql += " t.format <> 'ISO'"; if (!hyperType.equals(HypervisorType.None)) * { sql += " AND t.hypervisor_type = '" + hyperType.toString() + "'"; } } - * + * * if (bootable != null) { sql += " AND t.bootable = " + bootable; } - * + * * if (onlyReady){ sql += " AND thr.download_state = '" * +Status.DOWNLOADED.toString() + "'" + " AND thr.destroyed=0 "; if (zoneId * != null){ sql += " AND h.data_center_id = " +zoneId; } }else if (zoneId * != null){ sql += " AND tzr.zone_id = " +zoneId+ * " AND tzr.removed is null" ; }else{ sql += " AND tzr.removed is null "; } - * + * * if (zoneType != null){ sql += " AND dc.networktype = '" + zoneType + "'"; * } - * + * * if (!showDomr){ sql += " AND t.type != '" * +Storage.TemplateType.SYSTEM.toString() + "'"; } - * + * * sql += " AND t.removed IS NULL"; - * + * * return sql; } - * + * * private String getOrderByLimit(Long pageSize, Long startIndex) { Boolean * isAscending = * Boolean.parseBoolean(_configDao.getValue("sortkey.algorithm")); * isAscending = (isAscending == null ? true : isAscending); - * + * * String sql; if (isAscending) { sql = " ORDER BY t.sort_key ASC"; } else { * sql = " ORDER BY t.sort_key DESC"; } - * + * * if ((pageSize != null) && (startIndex != null)) { sql += " LIMIT " + * startIndex.toString() + "," + pageSize.toString(); } return sql; } */ @@ -849,17 +849,17 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * Long zoneId, final HypervisorType hyperType, final boolean onlyReady, * final boolean showDomr, final List permittedAccounts, final * Account caller, final Map tags) { - * + * * final String permittedAccountsStr = join(",", permittedAccounts); - * + * * final Transaction txn = Transaction.currentTxn(); txn.start(); - * + * * Set> templateZonePairList = new HashSet>(); PreparedStatement pstmt = null; ResultSet rs = null; try { - * + * * final StringBuilder joinClause = new StringBuilder(); final StringBuilder * whereClause = new StringBuilder(" WHERE t.removed IS NULL"); - * + * * if (isIso) { whereClause.append(" AND t.format = 'ISO'"); if * (!hyperType.equals(HypervisorType.None)) { joinClause.append( * " INNER JOIN guest_os guestOS on (guestOS.id = t.guest_os_id) INNER JOIN guest_os_hypervisor goh on ( goh.guest_os_id = guestOS.id) " @@ -873,20 +873,20 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * relatedHypers.setLength(relatedHypers.length() - 1); * whereClause.append(" AND t.hypervisor_type IN ("); * whereClause.append(relatedHypers); whereClause.append(")"); } } - * + * * joinClause.append( * " INNER JOIN template_s3_ref tsr on (t.id = tsr.template_id)"); - * + * * whereClause.append("AND t.name LIKE \"%"); whereClause.append(keyword == * null ? keyword : name); whereClause.append("%\""); - * + * * if (bootable != null) { whereClause.append(" AND t.bootable = "); * whereClause.append(bootable); } - * + * * if (!showDomr) { whereClause.append(" AND t.type != '"); * whereClause.append(Storage.TemplateType.SYSTEM); whereClause.append("'"); * } - * + * * if (templateFilter == TemplateFilter.featured) { * whereClause.append(" AND t.public = 1 AND t.featured = 1"); } else if * ((templateFilter == TemplateFilter.self || templateFilter == @@ -916,11 +916,11 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * (templateFilter == TemplateFilter.all && caller.getType() == * Account.ACCOUNT_TYPE_ADMIN) { } else if (caller.getType() != * Account.ACCOUNT_TYPE_ADMIN) { return templateZonePairList; } - * + * * final StringBuilder sql = new StringBuilder(SELECT_TEMPLATE_S3_REF); * sql.append(joinClause); sql.append(whereClause); * sql.append(getOrderByLimit(pageSize, startIndex)); - * + * * pstmt = txn.prepareStatement(sql.toString()); rs = pstmt.executeQuery(); * while (rs.next()) { final Pair templateZonePair = new * Pair( rs.getLong(1), -1L); @@ -928,46 +928,9 @@ public class VMTemplateDaoImpl extends GenericDaoBase implem * (Exception e) { s_logger.warn("Error listing S3 templates", e); if (txn * != null) { txn.rollback(); } } finally { closeResources(pstmt, rs); if * (txn != null) { txn.close(); } } - * + * * return templateZonePairList; } */ - @Override - public boolean updateState(TemplateState currentState, TemplateEvent event, TemplateState nextState, - VMTemplateVO vo, Object data) { - Long oldUpdated = vo.getUpdatedCount(); - Date oldUpdatedTime = vo.getUpdated(); - SearchCriteria sc = updateStateSearch.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, "updated", new Date()); - - int rows = update((VMTemplateVO) vo, sc); - if (rows == 0 && s_logger.isDebugEnabled()) { - VMTemplateVO dbVol = findByIdIncludingRemoved(vo.getId()); - if (dbVol != null) { - StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString()); - str.append(": DB Data={id=").append(dbVol.getId()).append("; state=").append(dbVol.getState()) - .append("; updatecount=").append(dbVol.getUpdatedCount()).append(";updatedTime=") - .append(dbVol.getUpdated()); - str.append(": New Data={id=").append(vo.getId()).append("; state=").append(nextState) - .append("; event=").append(event).append("; updatecount=").append(vo.getUpdatedCount()) - .append("; updatedTime=").append(vo.getUpdated()); - str.append(": stale Data={id=").append(vo.getId()).append("; state=").append(currentState) - .append("; event=").append(event).append("; updatecount=").append(oldUpdated) - .append("; updatedTime=").append(oldUpdatedTime); - } else { - s_logger.debug("Unable to update objectIndatastore: id=" + vo.getId() - + ", as there is no such object exists in the database anymore"); - } - } - return rows > 0; - } } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index 9b6382b80b7..c06756e4e9c 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -56,7 +56,6 @@ import org.apache.cloudstack.storage.datastore.DataObjectManager; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.image.store.TemplateObject; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; @@ -121,8 +120,6 @@ public class TemplateServiceImpl implements TemplateService { @Inject EndPointSelector _epSelector; @Inject - ImageDataManager imageMgr; - @Inject TemplateManager _tmpltMgr; class TemplateOpContext extends AsyncRpcConext { @@ -324,19 +321,6 @@ public class TemplateServiceImpl implements TemplateService { VMTemplateVO tmlpt = _templateDao.findById(tmplt.getId()); tmlpt.setSize(tmpltInfo.getSize()); _templateDao.update(tmplt.getId(), tmlpt); - // set template to ready state - if (tmplt.getState() != TemplateState.Ready) { - try { - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, - _templateDao); - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, - _templateDao); - } catch (NoTransitionException e) { - // non fatal though - s_logger.debug( - "failed to update template " + tmplt.getUniqueName() + " state to Ready", e); - } - } if (tmpltInfo.getSize() > 0 && tmplt.getUrl() != null) { long accountId = tmplt.getAccountId(); @@ -370,18 +354,7 @@ public class TemplateServiceImpl implements TemplateService { _templateDao.update(tmplt.getId(), tmlpt); associateTemplateToZone(tmplt.getId(), zoneId); - // set template to ready state - if (tmplt.getState() != TemplateState.Ready) { - try { - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, - _templateDao); - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, - _templateDao); - } catch (NoTransitionException e) { - // non fatal though - s_logger.debug("failed to update template " + tmplt.getUniqueName() + " state to Ready", e); - } - } + } } else { if (tmpltStore != null) { @@ -623,16 +596,6 @@ public class TemplateServiceImpl implements TemplateService { long storeId = store.getId(); List rtngTmplts = _templateDao.listAllSystemVMTemplates(); for (VMTemplateVO tmplt : rtngTmplts) { - // set template ready state - if (tmplt.getState() != TemplateState.Ready) { - try { - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.CreateRequested, null, _templateDao); - imageMgr.getStateMachine().transitTo(tmplt, TemplateEvent.OperationSucceeded, null, _templateDao); - } catch (NoTransitionException e) { - // non fatal though - s_logger.debug("failed to update system vm template state to Ready", e); - } - } TemplateDataStoreVO tmpltStore = _vmTemplateStoreDao.findByStoreTemplate(storeId, tmplt.getId()); if (tmpltStore == null) { tmpltStore = new TemplateDataStoreVO(storeId, tmplt.getId(), new Date(), 100, Status.DOWNLOADED, null, diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java deleted file mode 100644 index e1fd46b76df..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManager.java +++ /dev/null @@ -1,30 +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.image.manager; - -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; - -import com.cloud.storage.VMTemplateVO; -import com.cloud.utils.fsm.StateMachine2; - -public interface ImageDataManager { - StateMachine2 getStateMachine(); - -} diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java deleted file mode 100644 index f41416baf90..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/manager/ImageDataManagerImpl.java +++ /dev/null @@ -1,52 +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.image.manager; - -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateEvent; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; -import org.springframework.stereotype.Component; - -import com.cloud.storage.VMTemplateVO; -import com.cloud.utils.fsm.StateMachine2; - -@Component -public class ImageDataManagerImpl implements ImageDataManager { - private final StateMachine2 stateMachine = new StateMachine2(); - - public ImageDataManagerImpl() { - stateMachine.addTransition(TemplateState.Allocated, TemplateEvent.CreateRequested, TemplateState.Creating); - stateMachine.addTransition(TemplateState.Creating, TemplateEvent.CreateRequested, TemplateState.Creating); - stateMachine.addTransition(TemplateState.Creating, TemplateEvent.OperationSucceeded, TemplateState.Ready); - stateMachine.addTransition(TemplateState.Creating, TemplateEvent.OperationFailed, TemplateState.Allocated); - stateMachine.addTransition(TemplateState.Creating, TemplateEvent.DestroyRequested, TemplateState.Destroying); - stateMachine.addTransition(TemplateState.Ready, TemplateEvent.DestroyRequested, TemplateState.Destroying); - stateMachine.addTransition(TemplateState.Allocated, TemplateEvent.DestroyRequested, TemplateState.Destroying); - stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.DestroyRequested, TemplateState.Destroying); - stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationFailed, TemplateState.Destroying); - stateMachine.addTransition(TemplateState.Destroying, TemplateEvent.OperationSucceeded, TemplateState.Destroyed); - // TODO: this should not be needed, but it happened during testing where - // multiple success event is sent to callback - stateMachine.addTransition(TemplateState.Ready, TemplateEvent.OperationSucceeded, TemplateState.Ready); - } - - @Override - public StateMachine2 getStateMachine() { - return stateMachine; - } -} diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 9957791f061..72a8849d05f 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -33,7 +33,6 @@ import org.apache.cloudstack.storage.command.CopyCmdAnswer; import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; -import org.apache.cloudstack.storage.image.manager.ImageDataManager; import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.log4j.Logger; @@ -58,8 +57,6 @@ public class TemplateObject implements TemplateInfo { private VMTemplateVO imageVO; private DataStore dataStore; @Inject - ImageDataManager imageMgr; - @Inject VMTemplateDao imageDao; @Inject ObjectInDataStoreManager objectInStoreMgr; @@ -155,12 +152,12 @@ public class TemplateObject implements TemplateInfo { return this.imageVO.getFormat(); } - public boolean stateTransit(TemplateEvent e) throws NoTransitionException { - this.imageVO = imageDao.findById(this.imageVO.getId()); - boolean result = imageMgr.getStateMachine().transitTo(this.imageVO, e, null, imageDao); - this.imageVO = imageDao.findById(this.imageVO.getId()); - return result; - } +// public boolean stateTransit(TemplateEvent e) throws NoTransitionException { +// this.imageVO = imageDao.findById(this.imageVO.getId()); +// boolean result = imageMgr.getStateMachine().transitTo(this.imageVO, e, null, imageDao); +// this.imageVO = imageDao.findById(this.imageVO.getId()); +// return result; +// } @Override public void processEvent(Event event) { @@ -178,9 +175,9 @@ public class TemplateObject implements TemplateInfo { templEvent = TemplateEvent.OperationFailed; } - if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { - this.stateTransit(templEvent); - } +// if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { +// this.stateTransit(templEvent); +// } } objectInStoreMgr.update(this, event); @@ -241,9 +238,9 @@ public class TemplateObject implements TemplateInfo { templEvent = TemplateEvent.OperationFailed; } - if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { - this.stateTransit(templEvent); - } +// if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { +// this.stateTransit(templEvent); +// } } objectInStoreMgr.update(this, event); } catch (NoTransitionException e) { diff --git a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index 83291f84448..07930936b44 100644 --- a/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -27,6 +27,7 @@ import javax.inject.Inject; import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.response.TemplateResponse; import org.apache.cloudstack.api.response.TemplateZoneResponse; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -103,7 +104,7 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im templateResponse.setDisplayText(template.getDisplayText()); templateResponse.setPublic(template.isPublicTemplate()); templateResponse.setCreated(template.getCreatedOnStore()); - templateResponse.setReady(template.getState() == TemplateState.Ready); + templateResponse.setReady(template.getState() == ObjectInDataStoreStateMachine.State.Ready); templateResponse.setFeatured(template.isFeatured()); templateResponse.setExtractable(template.isExtractable() && !(template.getTemplateType() == TemplateType.SYSTEM)); templateResponse.setPasswordEnabled(template.isEnablePassword()); @@ -293,7 +294,13 @@ public class TemplateJoinDaoImpl extends GenericDaoBase im isoResponse.setPublic(iso.isPublicTemplate()); isoResponse.setExtractable(iso.isExtractable() && !(iso.getTemplateType() == TemplateType.PERHOST)); isoResponse.setCreated(iso.getCreatedOnStore()); - isoResponse.setReady(iso.getState() == TemplateState.Ready); + if ( iso.getTemplateType() == TemplateType.PERHOST ){ + // for xs-tools.iso and vmware-tools.iso, we didn't download, but is ready to use. + isoResponse.setReady(true); + } + else{ + isoResponse.setReady(iso.getState() == ObjectInDataStoreStateMachine.State.Ready); + } isoResponse.setBootable(iso.isBootable()); isoResponse.setFeatured(iso.isFeatured()); isoResponse.setCrossZones(iso.isCrossZones()); diff --git a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java index ef6d1ebce17..03dce9943b5 100644 --- a/server/src/com/cloud/api/query/vo/TemplateJoinVO.java +++ b/server/src/com/cloud/api/query/vo/TemplateJoinVO.java @@ -26,17 +26,12 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.cloudstack.api.Identity; -import org.apache.cloudstack.api.InternalIdentity; -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateState; - +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.storage.Storage; -import com.cloud.storage.Volume; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.utils.db.GenericDao; -import com.cloud.vm.VirtualMachine; @Entity @Table(name="template_view") @@ -240,9 +235,9 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { @Column(name="tag_customer") private String tagCustomer; - @Column(name="state") - @Enumerated(value=EnumType.STRING) - private TemplateState state; + @Column(name = "state") + @Enumerated(EnumType.STRING) + ObjectInDataStoreStateMachine.State state; public TemplateJoinVO() { } @@ -1021,16 +1016,15 @@ public class TemplateJoinVO extends BaseViewVO implements ControlledViewEntity { - public TemplateState getState() { - return state; - } + public ObjectInDataStoreStateMachine.State getState() { + return state; + } - public void setState(TemplateState state) { - this.state = state; - } - + public void setState(ObjectInDataStoreStateMachine.State state) { + this.state = state; + } } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 74d4caeb6a1..387e909d347 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1830,7 +1830,7 @@ CREATE VIEW `cloud`.`template_view` AS vm_template.display_text, vm_template.enable_password, vm_template.guest_os_id, - vm_template.state, + -- vm_template.state, guest_os.uuid guest_os_uuid, guest_os.display_name guest_os_name, vm_template.bootable, @@ -1860,6 +1860,7 @@ CREATE VIEW `cloud`.`template_view` AS data_center.name data_center_name, launch_permission.account_id lp_account_id, template_store_ref.store_id, + template_store_ref.state, template_store_ref.download_state, template_store_ref.download_pct, template_store_ref.error_str, @@ -1898,7 +1899,7 @@ CREATE VIEW `cloud`.`template_view` AS left join `cloud`.`data_center` ON template_zone_ref.zone_id = data_center.id left join - `cloud`.`image_store` ON image_store.data_center_id = data_center.id OR image_store.scope = 'REGION' + `cloud`.`image_store` ON image_store.removed is NULL AND (image_store.data_center_id = data_center.id OR image_store.scope = 'REGION') left join `cloud`.`template_store_ref` ON template_store_ref.template_id = vm_template.id AND template_store_ref.store_id = image_store.id left join From 0acce2c518cfca911d1ebcda80a62396b3cbec8f Mon Sep 17 00:00:00 2001 From: Min Chen Date: Fri, 14 Jun 2013 15:14:41 -0700 Subject: [PATCH 291/303] Remove extra / for template install path during sync. --- core/src/com/cloud/storage/template/TemplateLocation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/com/cloud/storage/template/TemplateLocation.java b/core/src/com/cloud/storage/template/TemplateLocation.java index 34626e52bda..161a663981d 100644 --- a/core/src/com/cloud/storage/template/TemplateLocation.java +++ b/core/src/com/cloud/storage/template/TemplateLocation.java @@ -159,7 +159,7 @@ public class TemplateLocation { public TemplateProp getTemplateInfo() { TemplateProp tmplInfo = new TemplateProp(); tmplInfo.id = Long.parseLong(_props.getProperty("id")); - tmplInfo.installPath = _templatePath + File.separator + _props.getProperty("filename"); + tmplInfo.installPath = _templatePath + _props.getProperty("filename"); // _templatePath endsWith / if (_resourceType == ResourceType.VOLUME){ tmplInfo.installPath = tmplInfo.installPath.substring(tmplInfo.installPath.indexOf("volumes")); }else { From a715eb8121b3e9b6bb61fe3db150580b22e4b3aa Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 14 Jun 2013 15:55:44 -0700 Subject: [PATCH 292/303] clean up storage related code, and add lru replacement algorithm for cache storage --- agent/src/com/cloud/agent/AgentShell.java | 1 + api/src/com/cloud/storage/StoragePool.java | 2 +- client/tomcatconf/applicationContext.xml.in | 1 + client/tomcatconf/log4j-cloud.xml.in | 4 + .../agent/test/BackupSnapshotCommandTest.java | 2 +- .../agent/test/CheckNetworkAnswerTest.java | 205 ++++++++++++ .../api/agent/test/SnapshotCommandTest.java | 2 +- .../api/test/ResizeVolumeCommandTest.java | 229 ------------- .../subsystem/api/storage/ClusterScope.java | 1 + .../api/storage/DataMigrationSubSystem.java | 30 -- .../api/storage/DataMotionService.java | 4 +- .../api/storage/DataMotionStrategy.java | 8 +- .../subsystem/api/storage/DataObject.java | 25 +- .../api/storage/DataObjectInStore.java | 10 +- .../api/storage/DataStoreDriver.java | 27 +- .../api/storage/DataStoreLifeCycle.java | 16 +- .../api/storage/DataStoreManager.java | 18 +- .../api/storage/DataStoreProvider.java | 25 +- .../api/storage/DataStoreProviderManager.java | 11 +- .../subsystem/api/storage/EndPoint.java | 10 +- .../api/storage/EndPointSelector.java | 10 +- .../subsystem/api/storage/HostScope.java | 1 + .../api/storage/ImageStoreProvider.java | 4 +- .../api/storage/PrimaryDataStoreDriver.java | 4 +- .../api/storage/PrimaryDataStoreInfo.java | 12 +- .../engine/subsystem/api/storage/Scope.java | 6 +- .../api/storage/SnapshotDataFactory.java | 6 +- .../subsystem/api/storage/SnapshotInfo.java | 10 +- .../api/storage/SnapshotService.java | 8 +- .../api/storage/SnapshotStrategy.java | 10 +- .../api/storage/StorageCacheManager.java | 8 +- .../api/storage/StorageOrchestrator.java | 76 ----- .../api/storage/StoragePoolAllocator.java | 2 +- .../api/storage/StorageSubSystem.java | 31 -- .../subsystem/api/storage/TemplateInfo.java | 4 +- .../api/storage/TemplateProfile.java | 312 ------------------ .../api/storage/TemplateService.java | 2 +- .../subsystem/api/storage/VolumeInfo.java | 18 +- .../subsystem/api/storage/VolumeProfile.java | 35 -- .../subsystem/api/storage/VolumeService.java | 3 +- .../subsystem/api/storage/ZoneScope.java | 1 + .../storage/command/CreateObjectCommand.java | 1 - .../storage/datastore/db/ImageStoreDao.java | 10 +- .../storage/datastore/db/ImageStoreVO.java | 10 + .../datastore/db/PrimaryDataStoreDaoImpl.java | 2 +- .../datastore/db/SnapshotDataStoreDao.java | 10 +- .../datastore/db/SnapshotDataStoreVO.java | 15 + .../storage/datastore/db/StoragePoolVO.java | 16 +- .../datastore/db/TemplateDataStoreDao.java | 8 +- .../datastore/db/TemplateDataStoreVO.java | 21 +- .../datastore/db/VolumeDataStoreDao.java | 12 +- .../datastore/db/VolumeDataStoreVO.java | 19 +- .../image/datastore/ImageStoreInfo.java | 4 +- .../cloudstack/storage/to/ImageStoreTO.java | 9 +- .../storage/to/PrimaryDataStoreTO.java | 6 + .../storage/to/SnapshotObjectTO.java | 6 + .../storage/to/TemplateObjectTO.java | 6 + .../cloudstack/storage/to/VolumeObjectTO.java | 6 + .../manager/StorageCacheManagerImpl.java | 162 ++++++--- .../StorageCacheReplacementAlgorithm.java} | 7 +- .../StorageCacheReplacementAlgorithmLRU.java | 106 ++++++ .../motion/AncientDataMotionStrategy.java | 15 +- .../storage/image/ImageOrchestrator.java | 29 -- .../storage/image/TemplateServiceImpl.java | 2 - .../image/downloader/ImageDownloader.java | 25 -- .../ImageStoreProviderManagerImpl.java | 1 - .../storage/image/store/ImageStoreImpl.java | 10 +- .../storage/image/store/TemplateObject.java | 42 +++ .../allocator/StorageAllocatorTest.java | 4 +- ...orageCacheReplacementAlgorithmLRUTest.java | 226 +++++++++++++ .../cloudstack/storage/test/SnapshotTest.java | 101 +++--- .../cloudstack/storage/test/VolumeTest.java | 95 +++--- .../test/resource/storageContext.xml | 5 +- .../storage/snapshot/SnapshotObject.java | 44 ++- .../storage/snapshot/SnapshotServiceImpl.java | 44 +-- .../snapshot/SnapshotStateMachineManager.java | 2 +- .../snapshot/XenserverSnapshotStrategy.java | 1 - .../storage/snapshot/db/SnapshotDao2.java | 25 -- .../storage/snapshot/db/SnapshotDao2Impl.java | 28 -- .../storage/snapshot/db/SnapshotVO.java | 296 ----------------- .../datastore/DataStoreManagerImpl.java | 10 - .../datastore/PrimaryDataStoreEntityImpl.java | 2 +- .../DataStoreProviderManagerImpl.java | 6 - .../image/BaseImageStoreDriverImpl.java | 28 -- .../datastore/PrimaryDataStoreHelper.java | 4 +- .../datastore/PrimaryDataStoreImpl.java | 9 +- .../driver/PrimaryDataStoreDriver.java | 16 - .../provider/DefaultHostListener.java | 2 +- .../storage/volume/VolumeEntityImpl.java | 201 ----------- .../storage/volume/VolumeObject.java | 41 +++ .../storage/volume/VolumeServiceImpl.java | 33 +- .../CloudStackImageStoreLifeCycleImpl.java | 18 - .../lifecycle/S3ImageStoreLifeCycleImpl.java | 28 -- .../driver/SampleImageStoreDriverImpl.java | 3 - .../SampleImageStoreLifeCycleImpl.java | 18 - .../SampleImageStoreProviderImpl.java | 2 - .../driver/SwiftImageStoreDriverImpl.java | 3 - .../SwiftImageStoreLifeCycleImpl.java | 48 +-- .../CloudStackPrimaryDataStoreDriverImpl.java | 56 +--- ...oudStackPrimaryDataStoreLifeCycleImpl.java | 12 - .../SamplePrimaryDataStoreDriverImpl.java | 95 +----- .../SamplePrimaryDataStoreLifeCycleImpl.java | 43 +-- .../SamplePrimaryDatastoreProviderImpl.java | 2 - .../SolidfirePrimaryDataStoreDriver.java | 47 +-- .../SolidfirePrimaryDataStoreProvider.java | 10 - .../src/com/cloud/configuration/Config.java | 5 +- .../src/com/cloud/server/StatsCollector.java | 89 ----- setup/db/db/schema-410to420.sql | 7 +- test/pom.xml | 2 +- 109 files changed, 1219 insertions(+), 2246 deletions(-) delete mode 100644 core/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java delete mode 100755 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java delete mode 100755 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java delete mode 100644 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java delete mode 100755 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java delete mode 100644 engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java rename engine/storage/{datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java => cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java} (79%) create mode 100644 engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java delete mode 100644 engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java delete mode 100644 engine/storage/image/src/org/apache/cloudstack/storage/image/downloader/ImageDownloader.java create mode 100644 engine/storage/integration-test/test/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java delete mode 100644 engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2.java delete mode 100644 engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2Impl.java delete mode 100644 engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java delete mode 100644 engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java delete mode 100644 engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java diff --git a/agent/src/com/cloud/agent/AgentShell.java b/agent/src/com/cloud/agent/AgentShell.java index cf454b8c89c..e7f114bc412 100644 --- a/agent/src/com/cloud/agent/AgentShell.java +++ b/agent/src/com/cloud/agent/AgentShell.java @@ -82,6 +82,7 @@ public class AgentShell implements IAgentShell, Daemon { private int _pingRetries; private final List _agents = new ArrayList(); + public AgentShell() { } diff --git a/api/src/com/cloud/storage/StoragePool.java b/api/src/com/cloud/storage/StoragePool.java index 8b95383c537..8f8b8644ddc 100644 --- a/api/src/com/cloud/storage/StoragePool.java +++ b/api/src/com/cloud/storage/StoragePool.java @@ -58,7 +58,7 @@ public interface StoragePool extends Identity, InternalIdentity { /** * @return available storage in bytes */ - long getAvailableBytes(); + long getUsedBytes(); Long getClusterId(); diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 8d251eed66f..181219a611f 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -815,6 +815,7 @@ + diff --git a/client/tomcatconf/log4j-cloud.xml.in b/client/tomcatconf/log4j-cloud.xml.in index 0e7f004eb80..fc1c29ef5e1 100755 --- a/client/tomcatconf/log4j-cloud.xml.in +++ b/client/tomcatconf/log4j-cloud.xml.in @@ -132,6 +132,10 @@ under the License. + + + + diff --git a/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java index 40083a8e1bc..989059322a9 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/BackupSnapshotCommandTest.java @@ -83,7 +83,7 @@ public class BackupSnapshotCommandTest { }; @Override - public long getAvailableBytes() { + public long getUsedBytes() { return 0L; }; diff --git a/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java b/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java index 1853d3967c9..4db65570f1b 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/CheckNetworkAnswerTest.java @@ -16,9 +16,15 @@ // under the License. package org.apache.cloudstack.api.agent.test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import com.cloud.agent.api.storage.ResizeVolumeCommand; +import com.cloud.agent.api.to.StorageFilerTO; +import com.cloud.storage.Storage; +import com.cloud.storage.StoragePool; +import com.cloud.storage.StoragePoolStatus; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; @@ -26,6 +32,10 @@ import org.mockito.Mockito; import com.cloud.agent.api.CheckNetworkAnswer; import com.cloud.agent.api.CheckNetworkCommand; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + public class CheckNetworkAnswerTest { CheckNetworkCommand cnc; CheckNetworkAnswer cna; @@ -59,4 +69,199 @@ public class CheckNetworkAnswerTest { boolean b = cna.executeInSequence(); assertFalse(b); } + + public static class ResizeVolumeCommandTest { + + public StoragePool dummypool = new StoragePool() { + @Override + public long getId() { + return 1L; + }; + + @Override + public String getName() { + return "name"; + }; + + @Override + public String getUuid() { + return "bed9f83e-cac3-11e1-ac8a-0050568b007e"; + }; + + @Override + public Storage.StoragePoolType getPoolType() { + return Storage.StoragePoolType.Filesystem; + }; + + @Override + public Date getCreated() { + Date date = null; + try { + date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss") + .parse("01/01/1970 12:12:12"); + } catch (ParseException e) { + e.printStackTrace(); + } + return date; + } + + @Override + public Date getUpdateTime() { + return new Date(); + }; + + @Override + public long getDataCenterId() { + return 0L; + }; + + @Override + public long getCapacityBytes() { + return 0L; + }; + + @Override + public long getUsedBytes() { + return 0L; + }; + + @Override + public Long getClusterId() { + return 0L; + }; + + @Override + public String getHostAddress() { + return "hostAddress"; + }; + + @Override + public String getPath() { + return "path"; + }; + + @Override + public String getUserInfo() { + return "userInfo"; + }; + + @Override + public boolean isShared() { + return false; + }; + + @Override + public boolean isLocal() { + return false; + }; + + @Override + public StoragePoolStatus getStatus() { + return StoragePoolStatus.Up; + }; + + @Override + public int getPort() { + return 25; + }; + + @Override + public Long getPodId() { + return 0L; + } + + @Override + public String getStorageProviderName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isInMaintenance() { + // TODO Auto-generated method stub + return false; + }; + }; + + Long newSize = 4194304L; + Long currentSize = 1048576L; + + ResizeVolumeCommand rv = new ResizeVolumeCommand("dummydiskpath", + new StorageFilerTO(dummypool), currentSize, newSize, false, + "vmName"); + + @Test + public void testExecuteInSequence() { + boolean b = rv.executeInSequence(); + assertFalse(b); + } + + @Test + public void testGetPath() { + String path = rv.getPath(); + assertTrue(path.equals("dummydiskpath")); + } + + @Test + public void testGetPoolUuid() { + String poolUuid = rv.getPoolUuid(); + assertTrue(poolUuid.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e")); + } + + @Test + public void testGetPool() { + StorageFilerTO pool = rv.getPool(); + + Long id = pool.getId(); + Long expectedL = 1L; + assertEquals(expectedL, id); + + String uuid = pool.getUuid(); + assertTrue(uuid.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e")); + + String host = pool.getHost(); + assertTrue(host.equals("hostAddress")); + + String path = pool.getPath(); + assertTrue(path.equals("path")); + + String userInfo = pool.getUserInfo(); + assertTrue(userInfo.equals("userInfo")); + + Integer port = pool.getPort(); + Integer expectedI = 25; + assertEquals(expectedI, port); + + Storage.StoragePoolType type = pool.getType(); + assertEquals(Storage.StoragePoolType.Filesystem, type); + + String str = pool.toString(); + assertTrue(str.equals("Pool[" + id.toString() + "|" + host + ":" + + port.toString() + "|" + path + "]")); + } + + @Test + public void testGetNewSize() { + long newSize = rv.getNewSize(); + assertTrue(newSize == 4194304L); + } + + @Test + public void testGetCurrentSize() { + long currentSize = rv.getCurrentSize(); + assertTrue(currentSize == 1048576L); + } + + @Test + public void testGetShrinkOk() { + assertFalse(rv.getShrinkOk()); + } + + @Test + public void testGetInstanceName() { + String vmName = rv.getInstanceName(); + assertTrue(vmName.equals("vmName")); + } + + } } diff --git a/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java b/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java index 56a1d221357..3076d453434 100644 --- a/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java +++ b/core/test/org/apache/cloudstack/api/agent/test/SnapshotCommandTest.java @@ -74,7 +74,7 @@ public class SnapshotCommandTest { return 0L; }; - public long getAvailableBytes() { + public long getUsedBytes() { return 0L; }; diff --git a/core/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java b/core/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java deleted file mode 100644 index 02085f577b6..00000000000 --- a/core/test/src/com/cloud/agent/api/test/ResizeVolumeCommandTest.java +++ /dev/null @@ -1,229 +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 src.com.cloud.agent.api.test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.junit.Test; - -import com.cloud.agent.api.storage.ResizeVolumeCommand; -import com.cloud.agent.api.to.StorageFilerTO; -import com.cloud.storage.Storage.StoragePoolType; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; - - -public class ResizeVolumeCommandTest { - - public StoragePool dummypool = new StoragePool() { - @Override - public long getId() { - return 1L; - }; - - @Override - public String getName() { - return "name"; - }; - - @Override - public String getUuid() { - return "bed9f83e-cac3-11e1-ac8a-0050568b007e"; - }; - - @Override - public StoragePoolType getPoolType() { - return StoragePoolType.Filesystem; - }; - - @Override - public Date getCreated() { - Date date = null; - try { - date = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss") - .parse("01/01/1970 12:12:12"); - } catch (ParseException e) { - e.printStackTrace(); - } - return date; - } - - @Override - public Date getUpdateTime() { - return new Date(); - }; - - @Override - public long getDataCenterId() { - return 0L; - }; - - @Override - public long getCapacityBytes() { - return 0L; - }; - - @Override - public long getAvailableBytes() { - return 0L; - }; - - @Override - public Long getClusterId() { - return 0L; - }; - - @Override - public String getHostAddress() { - return "hostAddress"; - }; - - @Override - public String getPath() { - return "path"; - }; - - @Override - public String getUserInfo() { - return "userInfo"; - }; - - @Override - public boolean isShared() { - return false; - }; - - @Override - public boolean isLocal() { - return false; - }; - - @Override - public StoragePoolStatus getStatus() { - return StoragePoolStatus.Up; - }; - - @Override - public int getPort() { - return 25; - }; - - @Override - public Long getPodId() { - return 0L; - } - - @Override - public String getStorageProviderName() { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean isInMaintenance() { - // TODO Auto-generated method stub - return false; - }; - }; - - Long newSize = 4194304L; - Long currentSize = 1048576L; - - ResizeVolumeCommand rv = new ResizeVolumeCommand("dummydiskpath", - new StorageFilerTO(dummypool), currentSize, newSize, false, - "vmName"); - - @Test - public void testExecuteInSequence() { - boolean b = rv.executeInSequence(); - assertFalse(b); - } - - @Test - public void testGetPath() { - String path = rv.getPath(); - assertTrue(path.equals("dummydiskpath")); - } - - @Test - public void testGetPoolUuid() { - String poolUuid = rv.getPoolUuid(); - assertTrue(poolUuid.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e")); - } - - @Test - public void testGetPool() { - StorageFilerTO pool = rv.getPool(); - - Long id = pool.getId(); - Long expectedL = 1L; - assertEquals(expectedL, id); - - String uuid = pool.getUuid(); - assertTrue(uuid.equals("bed9f83e-cac3-11e1-ac8a-0050568b007e")); - - String host = pool.getHost(); - assertTrue(host.equals("hostAddress")); - - String path = pool.getPath(); - assertTrue(path.equals("path")); - - String userInfo = pool.getUserInfo(); - assertTrue(userInfo.equals("userInfo")); - - Integer port = pool.getPort(); - Integer expectedI = 25; - assertEquals(expectedI, port); - - StoragePoolType type = pool.getType(); - assertEquals(StoragePoolType.Filesystem, type); - - String str = pool.toString(); - assertTrue(str.equals("Pool[" + id.toString() + "|" + host + ":" - + port.toString() + "|" + path + "]")); - } - - @Test - public void testGetNewSize() { - long newSize = rv.getNewSize(); - assertTrue(newSize == 4194304L); - } - - @Test - public void testGetCurrentSize() { - long currentSize = rv.getCurrentSize(); - assertTrue(currentSize == 1048576L); - } - - @Test - public void testGetShrinkOk() { - assertFalse(rv.getShrinkOk()); - } - - @Test - public void testGetInstanceName() { - String vmName = rv.getInstanceName(); - assertTrue(vmName.equals("vmName")); - } - -} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java index 15e6d45f9ca..b0ed7d7d52b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ClusterScope.java @@ -27,6 +27,7 @@ public class ClusterScope extends AbstractScope { private Long zoneId; public ClusterScope(Long clusterId, Long podId, Long zoneId) { + super(); this.clusterId = clusterId; this.podId = podId; this.zoneId = zoneId; diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java deleted file mode 100755 index ad810432fd2..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataMigrationSubSystem.java +++ /dev/null @@ -1,30 +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.engine.subsystem.api.storage; - -import java.net.URI; - -import com.cloud.org.Grouping; - -public interface DataMigrationSubSystem { - - Class getScopeCoverage(); - - void migrate(URI source, URI dest, String reservationId); -} 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 index 5a124aa2725..5e10a0ba7e7 100644 --- 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 @@ -26,9 +26,9 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; public interface DataMotionService { - public void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); + void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); - public void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, + void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback); } 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 index 5bff21f3c8a..6deb6c1afc0 100644 --- 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 @@ -26,13 +26,13 @@ import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.host.Host; public interface DataMotionStrategy { - public boolean canHandle(DataObject srcData, DataObject destData); + boolean canHandle(DataObject srcData, DataObject destData); - public boolean canHandle(Map volumeMap, Host srcHost, Host destHost); + boolean canHandle(Map volumeMap, Host srcHost, Host destHost); - public Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); + Void copyAsync(DataObject srcData, DataObject destData, AsyncCompletionCallback callback); - public Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, + Void copyAsync(Map volumeMap, VirtualMachineTO vmTo, Host srcHost, Host destHost, AsyncCompletionCallback callback); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java index 0cd21119a9b..c57b01ce8b0 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObject.java @@ -23,24 +23,29 @@ import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataTO; public interface DataObject { - public long getId(); + long getId(); - public String getUri(); + String getUri(); - public DataTO getTO(); + DataTO getTO(); - public DataStore getDataStore(); + DataStore getDataStore(); - public Long getSize(); + Long getSize(); - public DataObjectType getType(); + DataObjectType getType(); - // public DiskFormat getFormat(); - public String getUuid(); + String getUuid(); boolean delete(); - public void processEvent(ObjectInDataStoreStateMachine.Event event); + void processEvent(ObjectInDataStoreStateMachine.Event event); - public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer); + void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer); + + void incRefCount(); + + void decRefCount(); + + Long getRefCount(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java index 929774c67c9..95bb9b98c44 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataObjectInStore.java @@ -21,13 +21,13 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.utils.fsm.StateObject; public interface DataObjectInStore extends StateObject { - public String getInstallPath(); + String getInstallPath(); - public void setInstallPath(String path); + void setInstallPath(String path); - public long getObjectId(); + long getObjectId(); - public long getDataStoreId(); + long getDataStoreId(); - public ObjectInDataStoreStateMachine.State getObjectInStoreState(); + ObjectInDataStoreStateMachine.State getObjectInStoreState(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java index 21430805c67..1cb6e158489 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreDriver.java @@ -18,32 +18,23 @@ */ package org.apache.cloudstack.engine.subsystem.api.storage; -import java.util.Set; - +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; -import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; - public interface DataStoreDriver { - public String grantAccess(DataObject data, EndPoint ep); + void createAsync(DataObject data, AsyncCompletionCallback callback); - public boolean revokeAccess(DataObject data, EndPoint ep); + void deleteAsync(DataObject data, AsyncCompletionCallback callback); - public Set listObjects(DataStore store); + void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback); - public void createAsync(DataObject data, AsyncCompletionCallback callback); + boolean canCopy(DataObject srcData, DataObject destData); - public void deleteAsync(DataObject data, AsyncCompletionCallback callback); + void resize(DataObject data, AsyncCompletionCallback callback); - public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback); + DataTO getTO(DataObject data); - public boolean canCopy(DataObject srcData, DataObject destData); - - public void resize(DataObject data, AsyncCompletionCallback callback); - - public DataTO getTO(DataObject data); - - public DataStoreTO getStoreTO(DataStore store); + DataStoreTO getStoreTO(DataStore store); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java index bd8c6e0060c..1e893db6bb5 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/DataStoreLifeCycle.java @@ -24,21 +24,17 @@ import com.cloud.agent.api.StoragePoolInfo; import com.cloud.hypervisor.Hypervisor.HypervisorType; public interface DataStoreLifeCycle { - public DataStore initialize(Map dsInfos); + DataStore initialize(Map dsInfos); - public boolean attachCluster(DataStore store, ClusterScope scope); + boolean attachCluster(DataStore store, ClusterScope scope); - public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo); + boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo); boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType); - public boolean dettach(); + boolean maintain(DataStore store); - public boolean unmanaged(); + boolean cancelMaintain(DataStore store); - public boolean maintain(DataStore store); - - public boolean cancelMaintain(DataStore store); - - public boolean deleteDataStore(DataStore store); + boolean deleteDataStore(DataStore store); } 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 8617eb4c2ad..949b037c1bd 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 @@ -24,21 +24,17 @@ import java.util.Map; import com.cloud.storage.DataStoreRole; public interface DataStoreManager { - public DataStore getDataStore(long storeId, DataStoreRole role); + DataStore getDataStore(long storeId, DataStoreRole role); - public DataStore getPrimaryDataStore(long storeId); + DataStore getPrimaryDataStore(long storeId); - public DataStore getDataStore(String uuid, DataStoreRole role); + DataStore getDataStore(String uuid, DataStoreRole role); - public List getImageStoresByScope(ZoneScope scope); + List getImageStoresByScope(ZoneScope scope); - public DataStore getImageStore(long zoneId); + DataStore getImageStore(long zoneId); - public List getImageStoresByProvider(String provider); + List getImageCacheStores(Scope scope); - public List getImageCacheStores(Scope scope); - - public DataStore registerDataStore(Map params, String providerUuid); - - public List listImageStores(); + List listImageStores(); } 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 a13c60bd772..855f0854103 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 @@ -23,27 +23,26 @@ import java.util.Set; public interface DataStoreProvider { // constants for provider names - public static final String NFS_IMAGE = "NFS"; - public static final String S3_IMAGE = "S3"; - public static final String SWIFT_IMAGE = "Swift"; - public static final String SAMPLE_IMAGE = "Sample"; + static final String NFS_IMAGE = "NFS"; + static final String S3_IMAGE = "S3"; + static final String SWIFT_IMAGE = "Swift"; + static final String SAMPLE_IMAGE = "Sample"; - public static final String DEFAULT_PRIMARY = "DefaultPrimary"; + static final String DEFAULT_PRIMARY = "DefaultPrimary"; - public static enum DataStoreProviderType { + static enum DataStoreProviderType { PRIMARY, IMAGE, ImageCache } - public DataStoreLifeCycle getDataStoreLifeCycle(); + DataStoreLifeCycle getDataStoreLifeCycle(); - public DataStoreDriver getDataStoreDriver(); + DataStoreDriver getDataStoreDriver(); - public HypervisorHostListener getHostListener(); + HypervisorHostListener getHostListener(); - public String getName(); + String getName(); - public boolean configure(Map params); - - public Set getTypes(); + boolean configure(Map params); + Set getTypes(); } 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 84272ef412c..d25e10ed34a 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 @@ -24,14 +24,11 @@ import com.cloud.storage.DataStoreProviderApiService; import com.cloud.utils.component.Manager; public interface DataStoreProviderManager extends Manager, DataStoreProviderApiService { - public DataStoreProvider getDataStoreProvider(String name); + DataStoreProvider getDataStoreProvider(String name); - public DataStoreProvider getDefaultPrimaryDataStoreProvider(); + DataStoreProvider getDefaultPrimaryDataStoreProvider(); - public DataStoreProvider getDefaultImageDataStoreProvider(); - - public DataStoreProvider getDefaultCacheDataStoreProvider(); - - public List getDataStoreProviders(); + DataStoreProvider getDefaultImageDataStoreProvider(); + DataStoreProvider getDefaultCacheDataStoreProvider(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java index ed9c0ebe908..254c91d3544 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPoint.java @@ -22,13 +22,13 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; public interface EndPoint { - public long getId(); + long getId(); - public String getHostAddr(); + String getHostAddr(); - public String getPublicAddr(); + String getPublicAddr(); - public Answer sendMessage(Command cmd); + Answer sendMessage(Command cmd); - public void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); + void sendMessageAsync(Command cmd, AsyncCompletionCallback callback); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java index a51fad817c0..ca0cc2c970a 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/EndPointSelector.java @@ -21,19 +21,11 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import java.util.List; public interface EndPointSelector { - public EndPoint select(DataObject srcData, DataObject destData); + EndPoint select(DataObject srcData, DataObject destData); - /** - * @param object - * @return - */ EndPoint select(DataObject object); EndPoint select(DataStore store); - /** - * @param store - * @return - */ List selectAll(DataStore store); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java index ff33077146a..1ff381872e6 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/HostScope.java @@ -25,6 +25,7 @@ public class HostScope extends AbstractScope { private Long zoneId; public HostScope(Long hostId, Long zoneId) { + super(); this.hostId = hostId; this.zoneId = zoneId; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java index bde4fe4c597..0025ae1cde6 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ImageStoreProvider.java @@ -22,7 +22,7 @@ import com.cloud.storage.ScopeType; public interface ImageStoreProvider extends DataStoreProvider { - public boolean isScopeSupported(ScopeType scope); + boolean isScopeSupported(ScopeType scope); - public boolean needDownloadSysTemplate(); + boolean needDownloadSysTemplate(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java index ee355573a6c..2528a536d64 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreDriver.java @@ -22,7 +22,7 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; public interface PrimaryDataStoreDriver extends DataStoreDriver { - public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback); + void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback); - public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback); + void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java index c69cd3a75cb..95a5cc9778b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java @@ -25,15 +25,15 @@ import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StoragePool; public interface PrimaryDataStoreInfo extends StoragePool { - public boolean isHypervisorSupported(HypervisorType hypervisor); + boolean isHypervisorSupported(HypervisorType hypervisor); - public boolean isLocalStorageSupported(); + boolean isLocalStorageSupported(); - public boolean isVolumeDiskTypeSupported(DiskFormat diskType); + boolean isVolumeDiskTypeSupported(DiskFormat diskType); - public String getUuid(); + String getUuid(); - public StoragePoolType getPoolType(); + StoragePoolType getPoolType(); - public PrimaryDataStoreLifeCycle getLifeCycle(); + PrimaryDataStoreLifeCycle getLifeCycle(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java index 5c71f3cc220..8e43fa07fd8 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/Scope.java @@ -21,9 +21,9 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.ScopeType; public interface Scope { - public ScopeType getScopeType(); + ScopeType getScopeType(); - public boolean isSameScope(Scope scope); + boolean isSameScope(Scope scope); - public Long getScopeId(); + Long getScopeId(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java index 04b67d427c1..0b8d1f104e1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotDataFactory.java @@ -21,9 +21,9 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.DataStoreRole; public interface SnapshotDataFactory { - public SnapshotInfo getSnapshot(long snapshotId, DataStore store); + SnapshotInfo getSnapshot(long snapshotId, DataStore store); - public SnapshotInfo getSnapshot(DataObject obj, DataStore store); + SnapshotInfo getSnapshot(DataObject obj, DataStore store); - public SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role); + SnapshotInfo getSnapshot(long snapshotId, DataStoreRole role); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java index 91e0fd79fa9..8d6b76010fe 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotInfo.java @@ -19,15 +19,15 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.Snapshot; public interface SnapshotInfo extends DataObject, Snapshot { - public SnapshotInfo getParent(); + SnapshotInfo getParent(); - public String getPath(); + String getPath(); - public SnapshotInfo getChild(); + SnapshotInfo getChild(); - public VolumeInfo getBaseVolume(); + VolumeInfo getBaseVolume(); - public void addPayload(Object data); + void addPayload(Object data); Long getDataCenterId(); diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java index 67c88471dfc..d594a0728cb 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotService.java @@ -18,11 +18,11 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface SnapshotService { - public SnapshotResult takeSnapshot(SnapshotInfo snapshot); + SnapshotResult takeSnapshot(SnapshotInfo snapshot); - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); + SnapshotInfo backupSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(SnapshotInfo snapshot); + boolean deleteSnapshot(SnapshotInfo snapshot); - public boolean revertSnapshot(SnapshotInfo snapshot); + boolean revertSnapshot(SnapshotInfo snapshot); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java index 542246ae36f..86ae532e2dc 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/SnapshotStrategy.java @@ -19,15 +19,11 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.storage.Snapshot; public interface SnapshotStrategy { - public SnapshotInfo takeSnapshot(SnapshotInfo snapshot); + SnapshotInfo takeSnapshot(SnapshotInfo snapshot); - public SnapshotInfo backupSnapshot(SnapshotInfo snapshot); + SnapshotInfo backupSnapshot(SnapshotInfo snapshot); - public boolean deleteSnapshot(Long snapshotId); + boolean deleteSnapshot(Long snapshotId); - /** - * @param snapshot - * @return - */ boolean canHandle(Snapshot snapshot); } 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 index fd5211f1dd0..92724c91889 100644 --- 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 @@ -19,9 +19,9 @@ package org.apache.cloudstack.engine.subsystem.api.storage; public interface StorageCacheManager { - public DataStore getCacheStorage(Scope scope); + DataStore getCacheStorage(Scope scope); - public DataObject createCacheObject(DataObject data, Scope scope); + DataObject createCacheObject(DataObject data, Scope scope); /** * only create cache object in db @@ -33,4 +33,8 @@ public interface StorageCacheManager { DataObject getCacheObject(DataObject data, Scope scope); boolean deleteCacheObject(DataObject data); + + boolean releaseCacheObject(DataObject data); + + DataObject createCacheObject(DataObject data, DataStore store); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java deleted file mode 100755 index d4455c8059a..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageOrchestrator.java +++ /dev/null @@ -1,76 +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.engine.subsystem.api.storage; - -import java.util.List; - -import org.apache.cloudstack.engine.cloud.entity.api.TemplateEntity; -import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; -import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; - -import com.cloud.deploy.DeploymentPlan; - -public interface StorageOrchestrator { - - /** - * Prepares all storage ready for a VM to start - * - * @param vm - * @param reservationId - */ - void prepare(long vmId, DeploymentPlan plan, String reservationId); - - /** - * Releases all storage that were used for a VM shutdown - * - * @param vm - * @param disks - * @param reservationId - */ - void release(long vmId, String reservationId); - - /** - * Destroy all disks - * - * @param disks - * @param reservationId - */ - void destroy(List disks, String reservationId); - - /** - * Cancel a reservation - * - * @param reservationId - * reservation to - */ - void cancel(String reservationId); - - /** - * If attaching a volume in allocated state to a running vm, need to create - * this volume - */ - void prepareAttachDiskToVM(long diskId, long vmId, String reservationId); - - boolean createVolume(VolumeEntity volume, long dataStoreId, DiskFormat diskType); - - boolean createVolumeFromTemplate(VolumeEntity volume, long dataStoreId, DiskFormat dis, TemplateEntity template); - - VolumeEntity allocateVolumeInDb(long size, VolumeType type, String volName, Long templateId); -} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java index 13eb0de6f70..eccf0f4f6e1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StoragePoolAllocator.java @@ -47,5 +47,5 @@ public interface StoragePoolAllocator extends Adapter { List allocateToPool(DiskProfile dskCh, VirtualMachineProfile vmProfile, DeploymentPlan plan, ExcludeList avoid, int returnUpTo); - public static int RETURN_UPTO_ALL = -1; + static int RETURN_UPTO_ALL = -1; } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java deleted file mode 100644 index e5a74a452a1..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/StorageSubSystem.java +++ /dev/null @@ -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.engine.subsystem.api.storage; - -import java.net.URI; - -import com.cloud.org.Grouping; - -public interface StorageSubSystem { - String getType(); - - Class getScope(); - - URI grantAccess(String vol, String reservationId); - - URI RemoveAccess(String vol, String reservationId); -} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java index 91dba115e09..ceb5fc0f55b 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateInfo.java @@ -21,7 +21,7 @@ package org.apache.cloudstack.engine.subsystem.api.storage; import com.cloud.template.VirtualMachineTemplate; public interface TemplateInfo extends DataObject, VirtualMachineTemplate { - public String getUniqueName(); + String getUniqueName(); - public String getInstallPath(); + String getInstallPath(); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java deleted file mode 100755 index dcfd4074bfd..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateProfile.java +++ /dev/null @@ -1,312 +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.engine.subsystem.api.storage; - -import java.util.Map; - -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Storage.ImageFormat; -import com.cloud.template.VirtualMachineTemplate; - -public class TemplateProfile { - Long userId; - String name; - String displayText; - Integer bits; - Boolean passwordEnabled; - Boolean sshKeyEnbaled; - Boolean requiresHvm; - String url; - Boolean isPublic; - Boolean featured; - Boolean isExtractable; - ImageFormat format; - Long guestOsId; - Long zoneId; - HypervisorType hypervisorType; - String accountName; - Long domainId; - Long accountId; - String chksum; - Boolean bootable; - Long templateId; - VirtualMachineTemplate template; - String templateTag; - Map details; - - public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, - Boolean passwordEnabled, Boolean requiresHvm, String url, Boolean isPublic, Boolean featured, - Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, HypervisorType hypervisorType, - String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, Map details, - Boolean sshKeyEnabled) { - this.templateId = templateId; - this.userId = userId; - this.name = name; - this.displayText = displayText; - this.bits = bits; - this.passwordEnabled = passwordEnabled; - this.requiresHvm = requiresHvm; - this.url = url; - this.isPublic = isPublic; - this.featured = featured; - this.isExtractable = isExtractable; - this.format = format; - this.guestOsId = guestOsId; - this.zoneId = zoneId; - this.hypervisorType = hypervisorType; - this.accountName = accountName; - this.domainId = domainId; - this.accountId = accountId; - this.chksum = chksum; - this.bootable = bootable; - this.details = details; - this.sshKeyEnbaled = sshKeyEnabled; - } - - public TemplateProfile(Long userId, VirtualMachineTemplate template, Long zoneId) { - this.userId = userId; - this.template = template; - this.zoneId = zoneId; - } - - public TemplateProfile(Long templateId, Long userId, String name, String displayText, Integer bits, - Boolean passwordEnabled, Boolean requiresHvm, String url, Boolean isPublic, Boolean featured, - Boolean isExtractable, ImageFormat format, Long guestOsId, Long zoneId, HypervisorType hypervisorType, - String accountName, Long domainId, Long accountId, String chksum, Boolean bootable, String templateTag, - Map details, Boolean sshKeyEnabled) { - this(templateId, userId, name, displayText, bits, passwordEnabled, requiresHvm, url, isPublic, featured, - isExtractable, format, guestOsId, zoneId, hypervisorType, accountName, domainId, accountId, chksum, - bootable, details, sshKeyEnabled); - this.templateTag = templateTag; - } - - public Long getTemplateId() { - return templateId; - } - - public void setTemplateId(Long id) { - this.templateId = id; - } - - public Long getUserId() { - return userId; - } - - public void setUserId(Long userId) { - this.userId = userId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDisplayText() { - return displayText; - } - - public void setDisplayText(String text) { - this.displayText = text; - } - - public Integer getBits() { - return bits; - } - - public void setBits(Integer bits) { - this.bits = bits; - } - - public Boolean getPasswordEnabled() { - return passwordEnabled; - } - - public void setPasswordEnabled(Boolean enabled) { - this.passwordEnabled = enabled; - } - - public Boolean getRequiresHVM() { - return requiresHvm; - } - - public void setRequiresHVM(Boolean hvm) { - this.requiresHvm = hvm; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public Boolean getIsPublic() { - return isPublic; - } - - public void setIsPublic(Boolean is) { - this.isPublic = is; - } - - public Boolean getFeatured() { - return featured; - } - - public void setFeatured(Boolean featured) { - this.featured = featured; - } - - public Boolean getIsExtractable() { - return isExtractable; - } - - public void setIsExtractable(Boolean is) { - this.isExtractable = is; - } - - public ImageFormat getFormat() { - return format; - } - - public void setFormat(ImageFormat format) { - this.format = format; - } - - public Long getGuestOsId() { - return guestOsId; - } - - public void setGuestOsId(Long id) { - this.guestOsId = id; - } - - public Long getZoneId() { - return zoneId; - } - - public void setZoneId(Long id) { - this.zoneId = id; - } - - public HypervisorType getHypervisorType() { - return hypervisorType; - } - - public void setHypervisorType(HypervisorType type) { - this.hypervisorType = type; - } - - public Long getDomainId() { - return domainId; - } - - public void setDomainId(Long id) { - this.domainId = id; - } - - public Long getAccountId() { - return accountId; - } - - public void setAccountId(Long id) { - this.accountId = id; - } - - public String getCheckSum() { - return chksum; - } - - public void setCheckSum(String chksum) { - this.chksum = chksum; - } - - public Boolean getBootable() { - return this.bootable; - } - - public void setBootable(Boolean bootable) { - this.bootable = bootable; - } - - public VirtualMachineTemplate getTemplate() { - return template; - } - - public void setTemplate(VirtualMachineTemplate template) { - this.template = template; - } - - public String getTemplateTag() { - return templateTag; - } - - public void setTemplateTag(String templateTag) { - this.templateTag = templateTag; - } - - public Map getDetails() { - return this.details; - } - - public void setDetails(Map details) { - this.details = details; - } - - public void setSshKeyEnabled(Boolean enabled) { - this.sshKeyEnbaled = enabled; - } - - public Boolean getSshKeyEnabled() { - return this.sshKeyEnbaled; - } - - public String getImageStorageUri() { - return null; - } - - public void setLocalPath(String path) { - - } - - public String getLocalPath() { - return null; - } - - public String getJobId() { - return null; - } - - public void setTemplatePoolRefId(long id) { - - } - - public long getId() { - return 0; - } - - public long getTemplatePoolRefId() { - return 0; - } - - public long getSize() { - return 0; - } -} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java index 52e18f195f1..085fbbdb232 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java @@ -27,7 +27,7 @@ import com.cloud.storage.StoragePool; public interface TemplateService { - public class TemplateApiResult extends CommandResult { + class TemplateApiResult extends CommandResult { private final TemplateInfo template; public TemplateApiResult(TemplateInfo template) { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java index 463c0ff3538..3d7b1aa76cb 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeInfo.java @@ -23,21 +23,21 @@ import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.storage.Volume; public interface VolumeInfo extends DataObject, Volume { - public boolean isAttachedVM(); + boolean isAttachedVM(); - public void addPayload(Object data); + void addPayload(Object data); - public Object getpayload(); + Object getpayload(); - public HypervisorType getHypervisorType(); + HypervisorType getHypervisorType(); - public Long getLastPoolId(); + Long getLastPoolId(); - public String getAttachedVmName(); + String getAttachedVmName(); - public void processEventOnly(ObjectInDataStoreStateMachine.Event event); + void processEventOnly(ObjectInDataStoreStateMachine.Event event); - public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer); + void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer); - public boolean stateTransit(Volume.Event event); + boolean stateTransit(Volume.Event event); } diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java deleted file mode 100644 index 8701912f304..00000000000 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeProfile.java +++ /dev/null @@ -1,35 +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.engine.subsystem.api.storage; - -public class VolumeProfile { - private String _uri; - - public String getURI() { - return _uri; - } - - public String getPath() { - return null; - } - - public long getSize() { - return 0; - } -} diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java index 39479523271..f96ea4032d1 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VolumeService.java @@ -29,8 +29,7 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.host.Host; public interface VolumeService { - - public class VolumeApiResult extends CommandResult { + class VolumeApiResult extends CommandResult { private final VolumeInfo volume; public VolumeApiResult(VolumeInfo volume) { diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java index 9ba1d10012a..a0d75b5cc7c 100644 --- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java +++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/ZoneScope.java @@ -25,6 +25,7 @@ public class ZoneScope extends AbstractScope { private Long zoneId; public ZoneScope(Long zoneId) { + super(); this.zoneId = zoneId; } diff --git a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java index a282a51e78a..121a7ee449c 100644 --- a/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java +++ b/engine/api/src/org/apache/cloudstack/storage/command/CreateObjectCommand.java @@ -35,7 +35,6 @@ public final class CreateObjectCommand extends Command implements StorageSubSyst @Override public boolean executeInSequence() { - // TODO Auto-generated method stub return false; } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java index 8d63a82be69..70e9bb386e0 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/ImageStoreDao.java @@ -25,13 +25,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; import com.cloud.utils.db.GenericDao; public interface ImageStoreDao extends GenericDao { - public ImageStoreVO findByName(String name); + ImageStoreVO findByName(String name); - public List findByProvider(String provider); + List findByProvider(String provider); - public List findByScope(ZoneScope scope); + List findByScope(ZoneScope scope); - public List findImageCacheByScope(ZoneScope scope); + List findImageCacheByScope(ZoneScope scope); - public List listImageStores(); + List listImageStores(); } 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 3c903ad6e20..5ed48a3781c 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 @@ -80,6 +80,9 @@ public class ImageStoreVO implements ImageStore { @Column(name = "total_size") private Long totalSize; + @Column(name = "used_bytes") + private Long usedBytes; + public DataStoreRole getRole() { return role; } @@ -180,4 +183,11 @@ public class ImageStoreVO implements ImageStore { this.totalSize = totalSize; } + public Long getUsedBytes() { + return usedBytes; + } + + public void setUsedBytes(Long usedBytes) { + this.usedBytes = usedBytes; + } } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java index 08082870268..8f7826f4006 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/PrimaryDataStoreDaoImpl.java @@ -147,7 +147,7 @@ public class PrimaryDataStoreDaoImpl extends GenericDaoBase @Override public void updateAvailable(long id, long available) { StoragePoolVO pool = createForUpdate(id); - pool.setAvailableBytes(available); + pool.setUsedBytes(available); update(id, pool); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java index 48d0db28127..01f02208307 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreDao.java @@ -28,13 +28,13 @@ import com.cloud.utils.fsm.StateDao; public interface SnapshotDataStoreDao extends GenericDao, StateDao { - public List listByStoreId(long id, DataStoreRole role); + List listByStoreId(long id, DataStoreRole role); - public void deletePrimaryRecordsForStore(long id); + void deletePrimaryRecordsForStore(long id); - public SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId); + SnapshotDataStoreVO findByStoreSnapshot(DataStoreRole role, long storeId, long snapshotId); - public SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role); + SnapshotDataStoreVO findBySnapshot(long snapshotId, DataStoreRole role); - public List listDestroyed(long storeId); + List listDestroyed(long storeId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java index 6ceb0d0fcba..2ae3e8cdbda 100644 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java @@ -92,6 +92,9 @@ public class SnapshotDataStoreVO implements StateObject, StateDao { - public List listByStoreId(long id); + List listByStoreId(long id); - public List listDestroyed(long storeId); + List listDestroyed(long storeId); - public void deletePrimaryRecordsForStore(long id); + void deletePrimaryRecordsForStore(long id); - public void deletePrimaryRecordsForTemplate(long templateId); + void deletePrimaryRecordsForTemplate(long templateId); List listByTemplateStore(long templateId, long storeId); diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java index 2cee4d13e8e..c6b434dbc1a 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java @@ -71,7 +71,7 @@ public class TemplateDataStoreVO implements StateObject, StateDao { - public List listByStoreId(long id); + List listByStoreId(long id); - public void deletePrimaryRecordsForStore(long id); + void deletePrimaryRecordsForStore(long id); - public VolumeDataStoreVO findByVolume(long volumeId); + VolumeDataStoreVO findByVolume(long volumeId); - public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId); + VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId); - public VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId, boolean lock); + VolumeDataStoreVO findByStoreVolume(long storeId, long volumeId, boolean lock); - public List listDestroyed(long storeId); + List listDestroyed(long storeId); } diff --git a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java index d2e5c2585e1..222447fa4a5 100755 --- a/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java +++ b/engine/api/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java @@ -111,6 +111,9 @@ public class VolumeDataStoreVO implements StateObject getCacheStores() { + SearchCriteriaService sc = SearchCriteria2.create(ImageStoreVO.class); + sc.addAnd(sc.getEntity().getRole(), SearchCriteria.Op.EQ, DataStoreRole.ImageCache); + List imageStoreVOs = sc.list(); + List stores = new ArrayList(); + for (ImageStoreVO vo : imageStoreVOs) { + stores.add(dataStoreManager.getDataStore(vo.getId(), vo.getRole())); + } + return stores; + } + @Override public String getName() { // TODO Auto-generated method stub @@ -103,12 +124,59 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { @Override public boolean configure(String name, Map params) throws ConfigurationException { - // TODO Auto-generated method stub + cacheReplacementEnabled = Boolean.parseBoolean(configDao.getValue(Config.StorageCacheReplacementEnabled.key())); + cacheReplaceMentInterval = NumbersUtil.parseInt(configDao.getValue(Config.StorageCacheReplacementInterval.key()), 86400); + workers = NumbersUtil.parseInt(configDao.getValue(Config.ExpungeWorkers.key()), 10); + executors = Executors.newScheduledThreadPool(workers, new NamedThreadFactory("StorageCacheManager-cache-replacement")); return true; } + protected class CacheReplacementRunner implements Runnable { + + @Override + public void run() { + GlobalLock replacementLock = null; + try { + replacementLock = GlobalLock.getInternLock("storageCacheMgr.replacement"); + if (replacementLock.lock(3)) { + List stores = getCacheStores(); + Collections.shuffle(stores); + DataObject object = null; + DataStore findAStore = null; + for (DataStore store : stores) { + object = cacheReplacementAlgorithm.chooseOneToBeReplaced(store); + findAStore = store; + if (object != null) { + break; + } + } + + if (object == null) { + return; + } + + while(object != null) { + object.delete(); + object = cacheReplacementAlgorithm.chooseOneToBeReplaced(findAStore); + } + } + } catch (Exception e) { + s_logger.debug("Failed to execute CacheReplacementRunner: " + e.toString()); + } finally { + if (replacementLock != null) { + replacementLock.unlock(); + } + } + } + } + @Override public boolean start() { + if (cacheReplacementEnabled) { + Random generator = new Random(); + int initalDelay = generator.nextInt(cacheReplaceMentInterval); + executors.scheduleWithFixedDelay(new CacheReplacementRunner(), initalDelay, cacheReplaceMentInterval, TimeUnit.SECONDS); + } return true; } @@ -118,29 +186,17 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { return true; } - private class CreateCacheObjectContext extends AsyncRpcConext { - final AsyncCallFuture future; - - /** - * @param callback - */ - public CreateCacheObjectContext(AsyncCompletionCallback callback, AsyncCallFuture future) { - super(callback); - this.future = future; - } - - } - @Override - public DataObject createCacheObject(DataObject data, Scope scope) { - DataStore cacheStore = this.getCacheStorage(scope); - DataObjectInStore obj = objectInStoreMgr.findObject(data, cacheStore); + public DataObject createCacheObject(DataObject data, DataStore store) { + DataObjectInStore obj = objectInStoreMgr.findObject(data, store); if (obj != null && obj.getState() == ObjectInDataStoreStateMachine.State.Ready) { s_logger.debug("there is already one in the cache store"); - return objectInStoreMgr.get(data, cacheStore); + DataObject dataObj = objectInStoreMgr.get(data, store); + dataObj.incRefCount(); + return dataObj; } - DataObject objOnCacheStore = cacheStore.create(data); + DataObject objOnCacheStore = store.create(data); AsyncCallFuture future = new AsyncCallFuture(); CopyCommandResult result = null; @@ -154,6 +210,7 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { objOnCacheStore.processEvent(Event.OperationFailed); } else { objOnCacheStore.processEvent(Event.OperationSuccessed, result.getAnswer()); + objOnCacheStore.incRefCount(); return objOnCacheStore; } } catch (InterruptedException e) { @@ -167,28 +224,31 @@ public class StorageCacheManagerImpl implements StorageCacheManager, Manager { objOnCacheStore.processEvent(Event.OperationFailed); } } - return null; } + @Override + public DataObject createCacheObject(DataObject data, Scope scope) { + DataStore cacheStore = this.getCacheStorage(scope); + return this.createCacheObject(data, cacheStore); + } + @Override public DataObject getCacheObject(DataObject data, Scope scope) { DataStore cacheStore = this.getCacheStorage(scope); DataObject objOnCacheStore = cacheStore.create(data); - + objOnCacheStore.incRefCount(); return objOnCacheStore; } - protected Void createCacheObjectCallBack( - AsyncCallbackDispatcher callback, - CreateCacheObjectContext context) { - AsyncCallFuture future = context.future; - future.complete(callback.getResult()); - return null; + @Override + public boolean releaseCacheObject(DataObject data) { + data.decRefCount(); + return true; } @Override public boolean deleteCacheObject(DataObject data) { - return objectInStoreMgr.delete(data); + return data.getDataStore().delete(data); } } \ No newline at end of file diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java similarity index 79% rename from engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java rename to engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java index 3a59b21238b..f7a23febecd 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/DataMotionDriver.java +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithm.java @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.cloudstack.storage.motion; +package org.apache.cloudstack.storage.cache.manager; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; +import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -public interface DataMotionDriver { - public void copy(DataObject srcObj, DataObject destObj); +public interface StorageCacheReplacementAlgorithm { + DataObject chooseOneToBeReplaced(DataStore store); } diff --git a/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java new file mode 100644 index 00000000000..440bf53ebda --- /dev/null +++ b/engine/storage/cache/src/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRU.java @@ -0,0 +1,106 @@ +/* + * 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 com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; +import com.cloud.utils.DateUtil; +import com.cloud.utils.NumbersUtil; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.SearchCriteria2; +import com.cloud.utils.db.SearchCriteriaService; +import org.apache.cloudstack.engine.subsystem.api.storage.*; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; +import org.apache.commons.lang.math.NumberUtils; + +import java.util.Calendar; +import java.util.Date; +import javax.annotation.PostConstruct; +import javax.inject.Inject; + + + +public class StorageCacheReplacementAlgorithmLRU implements StorageCacheReplacementAlgorithm { + @Inject + ConfigurationDao configDao; + @Inject + TemplateDataFactory templateFactory; + @Inject + VolumeDataFactory volumeFactory; + @Inject + SnapshotDataFactory snapshotFactory; + + Integer unusedTimeInterval; + + public StorageCacheReplacementAlgorithmLRU() { + + } + + @PostConstruct + public void initialize() { + unusedTimeInterval = NumbersUtil.parseInt(configDao.getValue(Config.StorageCacheReplacementLRUTimeInterval.key()), 30); + } + + public void setUnusedTimeInterval(Integer interval) { + unusedTimeInterval = interval; + } + + @Override + public DataObject chooseOneToBeReplaced(DataStore store) { + Calendar cal = Calendar.getInstance(); + cal.setTime(DateUtil.now()); + cal.add(Calendar.DAY_OF_MONTH, -unusedTimeInterval.intValue()); + Date bef = cal.getTime(); + + SearchCriteriaService sc = SearchCriteria2.create(TemplateDataStoreVO.class); + sc.addAnd(sc.getEntity().getLastUpdated(), SearchCriteria.Op.LT, bef); + sc.addAnd(sc.getEntity().getState(), SearchCriteria.Op.EQ, ObjectInDataStoreStateMachine.State.Ready); + sc.addAnd(sc.getEntity().getDataStoreId(), SearchCriteria.Op.EQ, store.getId()); + sc.addAnd(sc.getEntity().getDataStoreRole(), SearchCriteria.Op.EQ, store.getRole()); + sc.addAnd(sc.getEntity().getRefCnt(), SearchCriteria.Op.EQ, 0); + TemplateDataStoreVO template = sc.find(); + if (template != null) { + return templateFactory.getTemplate(template.getTemplateId(), store); + } + + SearchCriteriaService volSc = SearchCriteria2.create(VolumeDataStoreVO.class); + volSc.addAnd(volSc.getEntity().getLastUpdated(), SearchCriteria.Op.LT, bef); + volSc.addAnd(volSc.getEntity().getState(), SearchCriteria.Op.EQ, ObjectInDataStoreStateMachine.State.Ready); + volSc.addAnd(volSc.getEntity().getDataStoreId(), SearchCriteria.Op.EQ, store.getId()); + volSc.addAnd(volSc.getEntity().getRefCnt(), SearchCriteria.Op.EQ, 0); + VolumeDataStoreVO volume = volSc.find(); + if (volume != null) { + return volumeFactory.getVolume(volume.getVolumeId(), store); + } + + SearchCriteriaService snapshotSc = SearchCriteria2.create(SnapshotDataStoreVO.class); + snapshotSc.addAnd(snapshotSc.getEntity().getLastUpdated(), SearchCriteria.Op.LT, bef); + snapshotSc.addAnd(snapshotSc.getEntity().getState(), SearchCriteria.Op.EQ, ObjectInDataStoreStateMachine.State.Ready); + snapshotSc.addAnd(snapshotSc.getEntity().getDataStoreId(), SearchCriteria.Op.EQ, store.getId()); + snapshotSc.addAnd(snapshotSc.getEntity().getRole(), SearchCriteria.Op.EQ, store.getRole()); + snapshotSc.addAnd(snapshotSc.getEntity().getRefCnt(), SearchCriteria.Op.EQ, 0); + SnapshotDataStoreVO snapshot = snapshotSc.find(); + if (snapshot != null) { + return snapshotFactory.getSnapshot(snapshot.getSnapshotId(), store); + } + + return null; + } +} 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 index a01d2d30139..631de6a47a3 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -172,10 +172,11 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { EndPoint ep = selector.select(srcData, destData); answer = ep.sendMessage(cmd); } - // clean up cache entry in case of failure - if (answer == null || !answer.getResult()) { - if (cacheData != null) { + if (cacheData != null) { + if (answer == null || !answer.getResult()) { cacheMgr.deleteCacheObject(cacheData); + } else { + cacheMgr.releaseCacheObject(cacheData); } } return answer; @@ -191,8 +192,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { protected DataObject cacheSnapshotChain(SnapshotInfo snapshot) { DataObject leafData = null; + DataStore store = cacheMgr.getCacheStorage(snapshot.getDataStore().getScope()); while (snapshot != null) { - DataObject cacheData = cacheMgr.createCacheObject(snapshot, snapshot.getDataStore().getScope()); + DataObject cacheData = cacheMgr.createCacheObject(snapshot, store); if (leafData == null) { leafData = cacheData; } @@ -202,7 +204,10 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) { - + while (snapshot != null) { + cacheMgr.deleteCacheObject(snapshot); + snapshot = snapshot.getParent(); + } } protected Answer copyVolumeFromSnapshot(DataObject snapObj, DataObject volObj) { diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java deleted file mode 100644 index e4141f3fa00..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/ImageOrchestrator.java +++ /dev/null @@ -1,29 +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.image; - -public interface ImageOrchestrator { - void registerTemplate(long templateId); - - void registerSnapshot(long snapshotId); - - void registerVolume(long volumeId); - - void registerIso(long isoId); -} diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java index c06756e4e9c..96c35f36f34 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java @@ -576,8 +576,6 @@ public class TemplateServiceImpl implements TemplateService { if (result.isFailed()) { res.setResult(result.getResult()); destTemplate.processEvent(Event.OperationFailed); - // remove entry from template_store_ref - destTemplate.getDataStore().delete(destTemplate); } else { destTemplate.processEvent(Event.OperationSuccessed, result.getAnswer()); } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/downloader/ImageDownloader.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/downloader/ImageDownloader.java deleted file mode 100644 index af572d49a5e..00000000000 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/downloader/ImageDownloader.java +++ /dev/null @@ -1,25 +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.image.downloader; - -import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo; - -public interface ImageDownloader { - public void downloadImage(TemplateInfo template); -} 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 73c960fef9e..64ef78f8e09 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 @@ -66,7 +66,6 @@ public class ImageStoreProviderManagerImpl implements ImageStoreProviderManager ImageStoreProvider provider = (ImageStoreProvider) providerManager.getDataStoreProvider(providerName); ImageStoreEntity imgStore = ImageStoreImpl .getDataStore(dataStore, driverMaps.get(provider.getName()), provider); - // TODO Auto-generated method stub return imgStore; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java index a3da304bccc..6d8e8e59c6f 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java @@ -24,6 +24,7 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; +import com.cloud.capacity.dao.CapacityDao; import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver; import org.apache.cloudstack.engine.subsystem.api.storage.ImageStoreProvider; @@ -52,10 +53,11 @@ public class ImageStoreImpl implements ImageStoreEntity { VMTemplateDao imageDao; @Inject private ObjectInDataStoreManager objectInStoreMgr; + @Inject + private CapacityDao capacityDao; protected ImageStoreDriver driver; protected ImageStoreVO imageDataStoreVO; protected ImageStoreProvider provider; - boolean needDownloadToCacheStorage = false; public ImageStoreImpl() { super(); @@ -77,13 +79,11 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public Set listTemplates() { - // TODO Auto-generated method stub return null; } @Override public DataStoreDriver getDriver() { - // TODO Auto-generated method stub return this.driver; } @@ -94,7 +94,6 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public long getId() { - // TODO Auto-generated method stub return this.imageDataStoreVO.getId(); } @@ -110,19 +109,16 @@ public class ImageStoreImpl implements ImageStoreEntity { @Override public TemplateInfo getTemplate(long templateId) { - // TODO Auto-generated method stub return null; } @Override public VolumeInfo getVolume(long volumeId) { - // TODO Auto-generated method stub return null; } @Override public SnapshotInfo getSnapshot(long snapshotId) { - // TODO Auto-generated method stub return null; } diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 72a8849d05f..5ab52de8500 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -258,6 +258,48 @@ public class TemplateObject implements TemplateInfo { } } + @Override + public void incRefCount() { + if (this.dataStore == null) { + return; + } + + if (this.dataStore.getRole() == DataStoreRole.Image || + this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findById(this.dataStore.getId()); + store.incrRefCnt(); + store.setLastUpdated(new Date()); + templateStoreDao.update(store.getId(), store); + } + } + + @Override + public void decRefCount() { + if (this.dataStore == null) { + return; + } + if (this.dataStore.getRole() == DataStoreRole.Image || + this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findById(this.dataStore.getId()); + store.decrRefCnt(); + store.setLastUpdated(new Date()); + templateStoreDao.update(store.getId(), store); + } + } + + @Override + public Long getRefCount() { + if (this.dataStore == null) { + return null; + } + if (this.dataStore.getRole() == DataStoreRole.Image || + this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findById(this.dataStore.getId()); + return store.getRefCnt(); + } + return null; + } + @Override public DataTO getTO() { DataTO to = null; diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java index 3d300de1060..40d9d418938 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/allocator/StorageAllocatorTest.java @@ -128,7 +128,7 @@ public class StorageAllocatorTest { storage.setClusterId(clusterId); storage.setStatus(StoragePoolStatus.Up); storage.setScope(ScopeType.CLUSTER); - storage.setAvailableBytes(1000); + storage.setUsedBytes(1000); storage.setCapacityBytes(20000); storage.setHostAddress(UUID.randomUUID().toString()); storage.setPath(UUID.randomUUID().toString()); @@ -170,7 +170,7 @@ public class StorageAllocatorTest { storage.setClusterId(clusterId); storage.setStatus(StoragePoolStatus.Up); storage.setScope(ScopeType.CLUSTER); - storage.setAvailableBytes(1000); + storage.setUsedBytes(1000); storage.setCapacityBytes(20000); storage.setHostAddress(UUID.randomUUID().toString()); storage.setPath(UUID.randomUUID().toString()); diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java new file mode 100644 index 00000000000..7d40ea796e1 --- /dev/null +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/cache/manager/StorageCacheReplacementAlgorithmLRUTest.java @@ -0,0 +1,226 @@ +/* + * 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 com.cloud.storage.DataStoreRole; +import com.cloud.storage.Storage; +import com.cloud.storage.VMTemplateVO; +import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.utils.DateUtil; +import com.cloud.utils.component.ComponentContext; +import junit.framework.Assert; +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.DataStoreProvider; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; +import org.apache.cloudstack.storage.datastore.db.ImageStoreDao; +import org.apache.cloudstack.storage.datastore.db.ImageStoreVO; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import javax.inject.Inject; +import java.util.Calendar; +import java.util.Date; +import java.util.UUID; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = "classpath:/storageContext.xml") +public class StorageCacheReplacementAlgorithmLRUTest { + @Inject + VMTemplateDao templateDao; + @Inject + ImageStoreDao imageStoreDao; + @Inject + TemplateDataStoreDao templateDataStoreDao; + @Inject + StorageCacheReplacementAlgorithmLRU cacheReplacementAlgorithm; + @Inject + DataStoreManager dataStoreManager; + @Before + public void setup() throws Exception { + ComponentContext.initComponentsLifeCycle(); + } + @Test + public void testSelectObject() { + cacheReplacementAlgorithm.setUnusedTimeInterval(1); + try { + VMTemplateVO template = new VMTemplateVO(); + template.setTemplateType(Storage.TemplateType.USER); + template.setUrl(UUID.randomUUID().toString()); + template.setUniqueName(UUID.randomUUID().toString()); + template.setName(UUID.randomUUID().toString()); + template.setPublicTemplate(true); + template.setFeatured(true); + template.setRequiresHvm(true); + template.setBits(64); + template.setFormat(Storage.ImageFormat.VHD); + template.setEnablePassword(true); + template.setEnableSshKey(true); + template.setGuestOSId(1); + template.setBootable(true); + template.setPrepopulate(true); + template.setCrossZones(true); + template.setExtractable(true); + template = templateDao.persist(template); + + VMTemplateVO template2 = new VMTemplateVO(); + template2.setTemplateType(Storage.TemplateType.USER); + template2.setUrl(UUID.randomUUID().toString()); + template2.setUniqueName(UUID.randomUUID().toString()); + template2.setName(UUID.randomUUID().toString()); + template2.setPublicTemplate(true); + template2.setFeatured(true); + template2.setRequiresHvm(true); + template2.setBits(64); + template2.setFormat(Storage.ImageFormat.VHD); + template2.setEnablePassword(true); + template2.setEnableSshKey(true); + template2.setGuestOSId(1); + template2.setBootable(true); + template2.setPrepopulate(true); + template2.setCrossZones(true); + template2.setExtractable(true); + template2 = templateDao.persist(template2); + + ImageStoreVO imageStoreVO = new ImageStoreVO(); + imageStoreVO.setRole(DataStoreRole.ImageCache); + imageStoreVO.setName(UUID.randomUUID().toString()); + imageStoreVO.setProviderName(DataStoreProvider.NFS_IMAGE); + imageStoreVO.setProtocol("nfs"); + imageStoreVO.setUrl(UUID.randomUUID().toString()); + imageStoreVO = imageStoreDao.persist(imageStoreVO); + + Calendar cal = Calendar.getInstance(); + cal.setTime(DateUtil.now()); + cal.add(Calendar.DAY_OF_MONTH, -2); + Date date = cal.getTime(); + + TemplateDataStoreVO templateStoreVO1 = new TemplateDataStoreVO(); + templateStoreVO1.setLastUpdated(date); + templateStoreVO1.setDataStoreRole(DataStoreRole.ImageCache); + templateStoreVO1.setDataStoreId(imageStoreVO.getId()); + templateStoreVO1.setState(ObjectInDataStoreStateMachine.State.Ready); + templateStoreVO1.setCopy(true); + templateStoreVO1.setTemplateId(template.getId()); + templateDataStoreDao.persist(templateStoreVO1); + + TemplateDataStoreVO templateStoreVO2 = new TemplateDataStoreVO(); + templateStoreVO2.setLastUpdated(date); + templateStoreVO2.setDataStoreRole(DataStoreRole.ImageCache); + templateStoreVO2.setDataStoreId(imageStoreVO.getId()); + templateStoreVO2.setState(ObjectInDataStoreStateMachine.State.Ready); + templateStoreVO2.setCopy(true); + templateStoreVO2.setTemplateId(template2.getId()); + templateDataStoreDao.persist(templateStoreVO2); + + DataStore store = dataStoreManager.getDataStore(imageStoreVO.getId(), DataStoreRole.ImageCache); + Assert.assertNotNull(cacheReplacementAlgorithm.chooseOneToBeReplaced(store)); + + } catch (Exception e) { + Assert.fail(); + } + } + + + @Test + public void testSelectObjectFailed() { + cacheReplacementAlgorithm.setUnusedTimeInterval(1); + try { + VMTemplateVO template = new VMTemplateVO(); + template.setTemplateType(Storage.TemplateType.USER); + template.setUrl(UUID.randomUUID().toString()); + template.setUniqueName(UUID.randomUUID().toString()); + template.setName(UUID.randomUUID().toString()); + template.setPublicTemplate(true); + template.setFeatured(true); + template.setRequiresHvm(true); + template.setBits(64); + template.setFormat(Storage.ImageFormat.VHD); + template.setEnablePassword(true); + template.setEnableSshKey(true); + template.setGuestOSId(1); + template.setBootable(true); + template.setPrepopulate(true); + template.setCrossZones(true); + template.setExtractable(true); + template = templateDao.persist(template); + + VMTemplateVO template2 = new VMTemplateVO(); + template2.setTemplateType(Storage.TemplateType.USER); + template2.setUrl(UUID.randomUUID().toString()); + template2.setUniqueName(UUID.randomUUID().toString()); + template2.setName(UUID.randomUUID().toString()); + template2.setPublicTemplate(true); + template2.setFeatured(true); + template2.setRequiresHvm(true); + template2.setBits(64); + template2.setFormat(Storage.ImageFormat.VHD); + template2.setEnablePassword(true); + template2.setEnableSshKey(true); + template2.setGuestOSId(1); + template2.setBootable(true); + template2.setPrepopulate(true); + template2.setCrossZones(true); + template2.setExtractable(true); + template2 = templateDao.persist(template2); + + ImageStoreVO imageStoreVO = new ImageStoreVO(); + imageStoreVO.setRole(DataStoreRole.ImageCache); + imageStoreVO.setName(UUID.randomUUID().toString()); + imageStoreVO.setProviderName(DataStoreProvider.NFS_IMAGE); + imageStoreVO.setProtocol("nfs"); + imageStoreVO.setUrl(UUID.randomUUID().toString()); + imageStoreVO = imageStoreDao.persist(imageStoreVO); + + + Date date = DateUtil.now(); + + TemplateDataStoreVO templateStoreVO1 = new TemplateDataStoreVO(); + templateStoreVO1.setLastUpdated(date); + templateStoreVO1.setDataStoreRole(DataStoreRole.ImageCache); + templateStoreVO1.setDataStoreId(imageStoreVO.getId()); + templateStoreVO1.setState(ObjectInDataStoreStateMachine.State.Ready); + templateStoreVO1.setCopy(true); + templateStoreVO1.setTemplateId(template.getId()); + templateDataStoreDao.persist(templateStoreVO1); + + TemplateDataStoreVO templateStoreVO2 = new TemplateDataStoreVO(); + templateStoreVO2.setLastUpdated(date); + templateStoreVO2.setDataStoreRole(DataStoreRole.ImageCache); + templateStoreVO2.setDataStoreId(imageStoreVO.getId()); + templateStoreVO2.setState(ObjectInDataStoreStateMachine.State.Ready); + templateStoreVO2.setCopy(true); + templateStoreVO2.setTemplateId(template2.getId()); + templateDataStoreDao.persist(templateStoreVO2); + + DataStore store = dataStoreManager.getDataStore(imageStoreVO.getId(), DataStoreRole.ImageCache); + Assert.assertNull(cacheReplacementAlgorithm.chooseOneToBeReplaced(store)); + + } catch (Exception e) { + Assert.fail(); + } + } + + +} diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java index 8210dfe45bd..2579a38157d 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/SnapshotTest.java @@ -26,6 +26,8 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; +import junit.framework.Assert; + import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; @@ -43,6 +45,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.LocalHostEndpoint; @@ -351,7 +354,7 @@ public class SnapshotTest extends CloudStackTestNGBase { return volume; } - public VolumeInfo createCopyBaseImage() { + public VolumeInfo createCopyBaseImage() throws InterruptedException, ExecutionException { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); @@ -361,45 +364,13 @@ public class SnapshotTest extends CloudStackTestNGBase { this.primaryStoreId, this.templateFactory.getTemplate(this.image.getId(), DataStoreRole.Image)); VolumeApiResult result; - try { - result = future.get(); - return result.getVolume(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return null; + result = future.get(); + Assert.assertTrue(result.isSuccess()); + return result.getVolume(); + } - @Test - public void createSnapshot() { - VolumeInfo vol = createCopyBaseImage(); - SnapshotVO snapshotVO = createSnapshotInDb(vol); - SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); - SnapshotInfo newSnapshot = null; - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot)) { - newSnapshot = strategy.takeSnapshot(snapshot); - } - } - AssertJUnit.assertNotNull(newSnapshot); - - LocalHostEndpoint ep = new MockLocalHostEndPoint(); - ep.setResource(new MockLocalNfsSecondaryStorageResource()); - Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); - - // delete snapshot - for (SnapshotStrategy strategy : this.snapshotStrategies) { - if (strategy.canHandle(snapshot)) { - strategy.deleteSnapshot(newSnapshot.getId()); - } - } - - Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp); - } + private VMTemplateVO createTemplateInDb() { VMTemplateVO image = new VMTemplateVO(); @@ -424,7 +395,7 @@ public class SnapshotTest extends CloudStackTestNGBase { } @Test - public void createVolumeFromSnapshot() { + public void createVolumeFromSnapshot() throws InterruptedException, ExecutionException { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); @@ -440,11 +411,13 @@ public class SnapshotTest extends CloudStackTestNGBase { VolumeVO volVO = createVolume(vol.getTemplateId(), vol.getPoolId()); VolumeInfo newVol = this.volFactory.getVolume(volVO.getId()); - this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); + AsyncCallFuture volFuture = this.volumeService.createVolumeFromSnapshot(newVol, newVol.getDataStore(), snapshot); + VolumeApiResult apiResult = volFuture.get(); + Assert.assertTrue(apiResult.isSuccess()); } @Test - public void deleteSnapshot() { + public void deleteSnapshot() throws InterruptedException, ExecutionException { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); @@ -466,7 +439,7 @@ public class SnapshotTest extends CloudStackTestNGBase { } @Test - public void createTemplateFromSnapshot() { + public void createTemplateFromSnapshot() throws InterruptedException, ExecutionException { VolumeInfo vol = createCopyBaseImage(); SnapshotVO snapshotVO = createSnapshotInDb(vol); SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); @@ -482,10 +455,46 @@ public class SnapshotTest extends CloudStackTestNGBase { LocalHostEndpoint ep = new LocalHostEndpoint(); ep.setResource(new MockLocalNfsSecondaryStorageResource()); Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(ep); - VMTemplateVO templateVO = createTemplateInDb(); - TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); - DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); - this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); + + try { + VMTemplateVO templateVO = createTemplateInDb(); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); + DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); + AsyncCallFuture templateFuture = this.imageService.createTemplateFromSnapshotAsync(snapshot, tmpl, imageStore); + TemplateApiResult apiResult = templateFuture.get(); + Assert.assertTrue(apiResult.isSuccess()); + } finally { + Mockito.when(epSelector.select(Matchers.any(DataObject.class), Matchers.any(DataObject.class))).thenReturn(remoteEp); + } + } + + @Test + public void createSnapshot() throws InterruptedException, ExecutionException { + VolumeInfo vol = createCopyBaseImage(); + SnapshotVO snapshotVO = createSnapshotInDb(vol); + SnapshotInfo snapshot = this.snapshotFactory.getSnapshot(snapshotVO.getId(), vol.getDataStore()); + SnapshotInfo newSnapshot = null; + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + newSnapshot = strategy.takeSnapshot(snapshot); + } + } + AssertJUnit.assertNotNull(newSnapshot); + + LocalHostEndpoint ep = new MockLocalHostEndPoint(); + ep.setResource(new MockLocalNfsSecondaryStorageResource()); + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(ep); + + try { + for (SnapshotStrategy strategy : this.snapshotStrategies) { + if (strategy.canHandle(snapshot)) { + boolean res = strategy.deleteSnapshot(newSnapshot.getId()); + Assert.assertTrue(res); + } + } + } finally { + Mockito.when(epSelector.select(Matchers.any(DataStore.class))).thenReturn(remoteEp); + } } } diff --git a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java index ef5c4caae96..70fdb1b5829 100644 --- a/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java +++ b/engine/storage/integration-test/test/org/apache/cloudstack/storage/test/VolumeTest.java @@ -26,6 +26,8 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; +import junit.framework.Assert; + import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager; @@ -39,6 +41,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; +import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService.TemplateApiResult; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.storage.RemoteHostEndPoint; @@ -237,6 +240,7 @@ public class VolumeTest extends CloudStackTestNGBase { TemplateObjectTO to = new TemplateObjectTO(); to.setPath(this.getImageInstallPath()); to.setFormat(ImageFormat.VHD); + to.setSize(100L); CopyCmdAnswer answer = new CopyCmdAnswer(to); templateOnStore.processEvent(Event.CreateOnlyRequested); templateOnStore.processEvent(Event.OperationSuccessed, answer); @@ -335,57 +339,52 @@ public class VolumeTest extends CloudStackTestNGBase { AssertJUnit.assertTrue(result.isSuccess()); VolumeInfo newVol = result.getVolume(); - this.volumeService.destroyVolume(newVol.getId()); + boolean res = this.volumeService.destroyVolume(newVol.getId()); + Assert.assertTrue(res); VolumeInfo vol = this.volFactory.getVolume(volume.getId()); - this.volumeService.expungeVolumeAsync(vol); + future = this.volumeService.expungeVolumeAsync(vol); + result = future.get(); + Assert.assertTrue(result.isSuccess()); } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Assert.fail(e.toString()); } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Assert.fail(e.toString()); } catch (ConcurrentOperationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + Assert.fail(e.toString()); } } @Test - public void testCreateDataDisk() { - DataStore primaryStore = createPrimaryDataStore(); - primaryStoreId = primaryStore.getId(); - primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); - VolumeVO volume = createVolume(null, primaryStore.getId()); - VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); - this.volumeService.createVolumeAsync(volInfo, primaryStore); - } - - @Test - public void testDeleteDisk() { + public void testCreateDataDisk() throws InterruptedException, ExecutionException { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(null, primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); - try { - VolumeApiResult result = future.get(); - VolumeInfo vol = result.getVolume(); + VolumeApiResult result = future.get(); + Assert.assertTrue(result.isSuccess()); + } - this.volumeService.destroyVolume(volInfo.getId()); - volInfo = this.volFactory.getVolume(vol.getId()); - this.volumeService.expungeVolumeAsync(volInfo); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ConcurrentOperationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + @Test + public void testDeleteDisk() throws InterruptedException, ExecutionException, ConcurrentOperationException { + DataStore primaryStore = createPrimaryDataStore(); + primaryStoreId = primaryStore.getId(); + primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); + VolumeVO volume = createVolume(null, primaryStore.getId()); + VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); + AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); + VolumeApiResult result = future.get(); + Assert.assertTrue(result.isSuccess()); + VolumeInfo vol = result.getVolume(); + + boolean res = this.volumeService.destroyVolume(volInfo.getId()); + Assert.assertTrue(res); + volInfo = this.volFactory.getVolume(vol.getId()); + future = this.volumeService.expungeVolumeAsync(volInfo); + result = future.get(); + Assert.assertTrue(result.isSuccess()); } private VMTemplateVO createTemplateInDb() { @@ -411,30 +410,24 @@ public class VolumeTest extends CloudStackTestNGBase { } @Test - public void testCreateTemplateFromVolume() { + public void testCreateTemplateFromVolume() throws InterruptedException, ExecutionException { DataStore primaryStore = createPrimaryDataStore(); primaryStoreId = primaryStore.getId(); primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId); VolumeVO volume = createVolume(null, primaryStore.getId()); VolumeInfo volInfo = this.volFactory.getVolume(volume.getId()); AsyncCallFuture future = this.volumeService.createVolumeAsync(volInfo, primaryStore); - try { - VolumeApiResult result = future.get(); - AssertJUnit.assertTrue(result.isSuccess()); - volInfo = result.getVolume(); - VMTemplateVO templateVO = createTemplateInDb(); - TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); - DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); + VolumeApiResult result = future.get(); - this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ExecutionException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + AssertJUnit.assertTrue(result.isSuccess()); + volInfo = result.getVolume(); + VMTemplateVO templateVO = createTemplateInDb(); + TemplateInfo tmpl = this.templateFactory.getTemplate(templateVO.getId(), DataStoreRole.Image); + DataStore imageStore = this.dataStoreMgr.getImageStore(this.dcId); + AsyncCallFuture templateResult = this.imageService.createTemplateFromVolumeAsync(volInfo, tmpl, imageStore); + TemplateApiResult templateApiResult = templateResult.get(); + Assert.assertTrue(templateApiResult.isSuccess()); } } diff --git a/engine/storage/integration-test/test/resource/storageContext.xml b/engine/storage/integration-test/test/resource/storageContext.xml index cc8e3bf9294..9f4f102edec 100644 --- a/engine/storage/integration-test/test/resource/storageContext.xml +++ b/engine/storage/integration-test/test/resource/storageContext.xml @@ -43,9 +43,7 @@ - - @@ -76,7 +74,6 @@ - @@ -88,4 +85,6 @@ + + diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index bd145733afc..03104882706 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -22,6 +22,7 @@ import java.util.Date; import javax.inject.Inject; +import com.cloud.storage.DataStoreRole; 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.SnapshotDataFactory; @@ -273,6 +274,47 @@ public class SnapshotObject implements SnapshotInfo { this.processEvent(event); } + public void incRefCount() { + if (this.store == null) { + return; + } + + if (this.store.getRole() == DataStoreRole.Image || + this.store.getRole() == DataStoreRole.ImageCache) { + SnapshotDataStoreVO store = snapshotStoreDao.findById(this.store.getId()); + store.incrRefCnt(); + store.setLastUpdated(new Date()); + snapshotStoreDao.update(store.getId(), store); + } + } + + @Override + public void decRefCount() { + if (this.store == null) { + return; + } + if (this.store.getRole() == DataStoreRole.Image || + this.store.getRole() == DataStoreRole.ImageCache) { + SnapshotDataStoreVO store = snapshotStoreDao.findById(this.store.getId()); + store.decrRefCnt(); + store.setLastUpdated(new Date()); + snapshotStoreDao.update(store.getId(), store); + } + } + + @Override + public Long getRefCount() { + if (this.store == null) { + return null; + } + if (this.store.getRole() == DataStoreRole.Image || + this.store.getRole() == DataStoreRole.ImageCache) { + SnapshotDataStoreVO store = snapshotStoreDao.findById(this.store.getId()); + return store.getRefCnt(); + } + return null; + } + @Override public ObjectInDataStoreStateMachine.State getStatus() { return this.objectInStoreMgr.findObject(this, store).getObjectInStoreState(); @@ -280,8 +322,6 @@ public class SnapshotObject implements SnapshotInfo { @Override public void addPayload(Object data) { - // TODO Auto-generated method stub - } @Override diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java index ed538114177..631d220f69d 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotServiceImpl.java @@ -17,23 +17,19 @@ package org.apache.cloudstack.storage.snapshot; -import java.util.concurrent.ExecutionException; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionService; -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.ObjectInDataStoreStateMachine; +import com.cloud.dc.dao.ClusterDao; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.Snapshot; +import com.cloud.storage.VolumeManager; +import com.cloud.storage.dao.SnapshotDao; +import com.cloud.storage.dao.VolumeDao; +import com.cloud.storage.snapshot.SnapshotManager; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.fsm.NoTransitionException; +import com.cloud.vm.dao.UserVmDao; +import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import org.apache.cloudstack.engine.subsystem.api.storage.*; import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotResult; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCallFuture; import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; @@ -47,19 +43,8 @@ import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.VolumeManager; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.snapshot.SnapshotManager; -import com.cloud.utils.db.DB; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.fsm.NoTransitionException; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.snapshot.dao.VMSnapshotDao; +import javax.inject.Inject; +import java.util.concurrent.ExecutionException; @Component public class SnapshotServiceImpl implements SnapshotService { @@ -391,7 +376,6 @@ public class SnapshotServiceImpl implements SnapshotService { @Override public boolean revertSnapshot(SnapshotInfo snapshot) { - // TODO Auto-generated method stub return false; } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java index f07db7ed9a0..2ad4ae7d073 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotStateMachineManager.java @@ -22,5 +22,5 @@ import com.cloud.storage.SnapshotVO; import com.cloud.utils.fsm.NoTransitionException; public interface SnapshotStateMachineManager { - public void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException; + void processEvent(SnapshotVO snapshot, Event event) throws NoTransitionException; } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java index 0c3f31c9ef8..92af8c2b071 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/XenserverSnapshotStrategy.java @@ -194,7 +194,6 @@ public class XenserverSnapshotStrategy extends SnapshotStrategyBase { @Override public SnapshotInfo takeSnapshot(SnapshotInfo snapshot) { snapshot = snapshotSvr.takeSnapshot(snapshot).getSnashot(); - // TODO: add async return this.backupSnapshot(snapshot); } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2.java deleted file mode 100644 index d531ede0aba..00000000000 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2.java +++ /dev/null @@ -1,25 +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.snapshot.db; - -import com.cloud.utils.db.GenericDao; - -public interface SnapshotDao2 extends GenericDao { - -} diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2Impl.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2Impl.java deleted file mode 100644 index 74cec5e76e5..00000000000 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotDao2Impl.java +++ /dev/null @@ -1,28 +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.snapshot.db; - -import org.springframework.stereotype.Component; - -import com.cloud.utils.db.GenericDaoBase; - -@Component -public class SnapshotDao2Impl extends GenericDaoBase implements SnapshotDao2 { - -} diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java deleted file mode 100644 index 43ec6097cac..00000000000 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/db/SnapshotVO.java +++ /dev/null @@ -1,296 +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.snapshot.db; - -import java.util.Date; -import java.util.UUID; - -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 com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.Snapshot.State; -import com.cloud.storage.Snapshot.Type; -import com.cloud.utils.db.GenericDao; -import com.google.gson.annotations.Expose; - -@Entity -@Table(name = "snapshots") -public class SnapshotVO { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "id") - private final long id = -1; - - @Column(name = "data_center_id") - long dataCenterId; - - @Column(name = "account_id") - long accountId; - - @Column(name = "domain_id") - long domainId; - - @Column(name = "volume_id") - Long volumeId; - - @Column(name = "disk_offering_id") - Long diskOfferingId; - - @Expose - @Column(name = "path") - String path; - - @Expose - @Column(name = "name") - String name; - - @Expose - @Column(name = "status", updatable = true, nullable = false) - @Enumerated(value = EnumType.STRING) - private State status; - - @Column(name = "snapshot_type") - short snapshotType; - - @Column(name = "type_description") - String typeDescription; - - @Column(name = "size") - long size; - - @Column(name = GenericDao.CREATED_COLUMN) - Date created; - - @Column(name = GenericDao.REMOVED_COLUMN) - Date removed; - - @Column(name = "backup_snap_id") - String backupSnapshotId; - - @Column(name = "swift_id") - Long swiftId; - - @Column(name = "s3_id") - Long s3Id; - - @Column(name = "sechost_id") - Long secHostId; - - @Column(name = "prev_snap_id") - long prevSnapshotId; - - @Column(name = "hypervisor_type") - @Enumerated(value = EnumType.STRING) - HypervisorType hypervisorType; - - @Expose - @Column(name = "version") - String version; - - @Column(name = "uuid") - String uuid; - - public SnapshotVO() { - this.uuid = UUID.randomUUID().toString(); - } - - public SnapshotVO(long dcId, long accountId, long domainId, Long volumeId, Long diskOfferingId, String path, - String name, short snapshotType, String typeDescription, long size, HypervisorType hypervisorType) { - this.dataCenterId = dcId; - this.accountId = accountId; - this.domainId = domainId; - this.volumeId = volumeId; - this.diskOfferingId = diskOfferingId; - this.path = path; - this.name = name; - this.snapshotType = snapshotType; - this.typeDescription = typeDescription; - this.size = size; - this.status = State.Creating; - this.prevSnapshotId = 0; - this.hypervisorType = hypervisorType; - this.version = "2.2"; - this.uuid = UUID.randomUUID().toString(); - } - - public long getId() { - return id; - } - - public long getDataCenterId() { - return dataCenterId; - } - - public long getAccountId() { - return accountId; - } - - public long getDomainId() { - return domainId; - } - - public long getVolumeId() { - return volumeId; - } - - public long getDiskOfferingId() { - return diskOfferingId; - } - - public void setVolumeId(Long volumeId) { - this.volumeId = volumeId; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String getName() { - return name; - } - - public short getsnapshotType() { - return snapshotType; - } - - public Type getType() { - if (snapshotType < 0 || snapshotType >= Type.values().length) { - return null; - } - return Type.values()[snapshotType]; - } - - public Long getSwiftId() { - return swiftId; - } - - public void setSwiftId(Long swiftId) { - this.swiftId = swiftId; - } - - public Long getSecHostId() { - return secHostId; - } - - public void setSecHostId(Long secHostId) { - this.secHostId = secHostId; - } - - public HypervisorType getHypervisorType() { - return hypervisorType; - } - - public void setSnapshotType(short snapshotType) { - this.snapshotType = snapshotType; - } - - public boolean isRecursive() { - if (snapshotType >= Type.HOURLY.ordinal() && snapshotType <= Type.MONTHLY.ordinal()) { - return true; - } - return false; - } - - public long getSize() { - return size; - } - - public String getTypeDescription() { - return typeDescription; - } - - public void setTypeDescription(String typeDescription) { - this.typeDescription = typeDescription; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public Date getCreated() { - return created; - } - - public Date getRemoved() { - return removed; - } - - public State getStatus() { - return status; - } - - public void setStatus(State status) { - this.status = status; - } - - public String getBackupSnapshotId() { - return backupSnapshotId; - } - - public long getPrevSnapshotId() { - return prevSnapshotId; - } - - public void setBackupSnapshotId(String backUpSnapshotId) { - this.backupSnapshotId = backUpSnapshotId; - } - - public void setPrevSnapshotId(long prevSnapshotId) { - this.prevSnapshotId = prevSnapshotId; - } - - public static Type getSnapshotType(String snapshotType) { - for (Type type : Type.values()) { - if (type.equals(snapshotType)) { - return type; - } - } - return null; - } - - public String getUuid() { - return this.uuid; - } - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - public Long getS3Id() { - return s3Id; - } - - public void setS3Id(Long s3Id) { - this.s3Id = s3Id; - } - -} diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java index 7120da175d0..b92f92f655e 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/DataStoreManagerImpl.java @@ -54,11 +54,6 @@ public class DataStoreManagerImpl implements DataStoreManager { throw new CloudRuntimeException("un recognized type" + role); } - @Override - public DataStore registerDataStore(Map params, String providerUuid) { - return null; - } - @Override public DataStore getDataStore(String uuid, DataStoreRole role) { if (role == DataStoreRole.Primary) { @@ -84,11 +79,6 @@ public class DataStoreManagerImpl implements DataStoreManager { return stores.get(0); } - @Override - public List getImageStoresByProvider(String provider) { - return imageDataStoreMgr.listImageStoreByProvider(provider); - } - @Override public DataStore getPrimaryDataStore(long storeId) { return primaryStorMgr.getPrimaryDataStore(storeId); diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java index f62adfce999..e861910116a 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreEntityImpl.java @@ -170,7 +170,7 @@ public class PrimaryDataStoreEntityImpl implements StorageEntity { } @Override - public long getAvailableBytes() { + public long getUsedBytes() { // TODO Auto-generated method stub return 0; } diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java index db056e9e4c0..50238a89a70 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/provider/DataStoreProviderManagerImpl.java @@ -57,12 +57,6 @@ public class DataStoreProviderManagerImpl extends ManagerBase implements DataSto return providerMap.get(name); } - @Override - public List getDataStoreProviders() { - // TODO Auto-generated method stub - return null; - } - public List getPrimaryDataStoreProviders() { List providers = new ArrayList(); for (DataStoreProvider provider : providerMap.values()) { diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java index 561c8c446b3..93b0c2b373d 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java @@ -66,30 +66,11 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { @Inject EndPointSelector _epSelector; - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } - @Override public DataTO getTO(DataObject data) { return null; } - - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } - class CreateContext extends AsyncRpcConext { final DataObject data; @@ -202,8 +183,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { return null; } - - @Override public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { DeleteCommand cmd = new DeleteCommand(data.getTO()); @@ -224,21 +203,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { @Override public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub return false; } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } - - } diff --git a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java index 70e5a5a7b23..6815dec4d99 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java +++ b/engine/storage/src/org/apache/cloudstack/storage/volume/datastore/PrimaryDataStoreHelper.java @@ -108,12 +108,12 @@ public class PrimaryDataStoreHelper { StoragePoolVO pool = this.dataStoreDao.findById(store.getId()); pool.setScope(scope.getScopeType()); - pool.setAvailableBytes(existingInfo.getAvailableBytes()); + pool.setUsedBytes(existingInfo.getAvailableBytes()); pool.setCapacityBytes(existingInfo.getCapacityBytes()); pool.setStatus(StoragePoolStatus.Up); this.dataStoreDao.update(pool.getId(), pool); this.storageMgr.createCapacityEntry(pool, Capacity.CAPACITY_TYPE_LOCAL_STORAGE, - pool.getCapacityBytes() - pool.getAvailableBytes()); + pool.getUsedBytes()); return dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary); } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java index 1fc82510b50..cfdb5c0821d 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/PrimaryDataStoreImpl.java @@ -168,19 +168,16 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public boolean isHypervisorSupported(HypervisorType hypervisor) { - // TODO Auto-generated method stub return true; } @Override public boolean isLocalStorageSupported() { - // TODO Auto-generated method stub return false; } @Override public boolean isVolumeDiskTypeSupported(DiskFormat diskType) { - // TODO Auto-generated method stub return false; } @@ -216,13 +213,11 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { @Override public SnapshotInfo getSnapshot(long snapshotId) { - // TODO Auto-generated method stub return null; } @Override public DiskFormat getDefaultDiskType() { - // TODO Auto-generated method stub return null; } @@ -288,8 +283,8 @@ public class PrimaryDataStoreImpl implements PrimaryDataStore { } @Override - public long getAvailableBytes() { - return this.pdsv.getAvailableBytes(); + public long getUsedBytes() { + return this.pdsv.getUsedBytes(); } @Override diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java deleted file mode 100644 index b248758bc12..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/driver/PrimaryDataStoreDriver.java +++ /dev/null @@ -1,16 +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. diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java index 6431308ff74..fa5e2167cc8 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/datastore/provider/DefaultHostListener.java @@ -81,7 +81,7 @@ public class DefaultHostListener implements HypervisorHostListener { } StoragePoolVO poolVO = this.primaryStoreDao.findById(poolId); - poolVO.setAvailableBytes(mspAnswer.getPoolInfo().getAvailableBytes()); + poolVO.setUsedBytes(mspAnswer.getPoolInfo().getAvailableBytes()); poolVO.setCapacityBytes(mspAnswer.getPoolInfo().getCapacityBytes()); primaryStoreDao.update(pool.getId(), poolVO); diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java deleted file mode 100644 index 454a50c38bf..00000000000 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeEntityImpl.java +++ /dev/null @@ -1,201 +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; - -import java.lang.reflect.Method; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import org.apache.cloudstack.engine.cloud.entity.api.SnapshotEntity; -import org.apache.cloudstack.engine.cloud.entity.api.VolumeEntity; -import org.apache.cloudstack.engine.datacenter.entity.api.StorageEntity; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult; -import org.apache.cloudstack.engine.subsystem.api.storage.disktype.DiskFormat; -import org.apache.cloudstack.engine.subsystem.api.storage.type.VolumeType; -import org.apache.cloudstack.storage.datastore.PrimaryDataStoreEntityImpl; - -public class VolumeEntityImpl implements VolumeEntity { - private VolumeInfo volumeInfo; - private final VolumeService vs; - private VolumeApiResult result; - - public VolumeEntityImpl() { - this.vs = null; - } - - public VolumeEntityImpl(VolumeInfo volumeObject, VolumeService vs) { - this.volumeInfo = volumeObject; - this.vs = vs; - } - - public VolumeInfo getVolumeInfo() { - return volumeInfo; - } - - @Override - public String getUuid() { - return volumeInfo.getUuid(); - } - - @Override - public long getId() { - return volumeInfo.getId(); - } - - public String getExternalId() { - // TODO Auto-generated method stub - return null; - } - - @Override - public String getCurrentState() { - return null; - } - - @Override - public String getDesiredState() { - return null; - } - - @Override - public Date getCreatedTime() { - return null; - } - - @Override - public Date getLastUpdatedTime() { - return null; - } - - @Override - public String getOwner() { - return null; - } - - @Override - public List getApplicableActions() { - // TODO Auto-generated method stub - return null; - } - - @Override - public SnapshotEntity takeSnapshotOf(boolean full) { - // TODO Auto-generated method stub - return null; - } - - @Override - public String reserveForMigration(long expirationTime) { - // TODO Auto-generated method stub - return null; - } - - @Override - public void migrate(String reservationToken) { - // TODO Auto-generated method stub - - } - - @Override - public VolumeEntity setupForCopy() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void copy(VolumeEntity dest) { - // TODO Auto-generated method stub - - } - - @Override - public void attachTo(String vm, long deviceId) { - // TODO Auto-generated method stub - - } - - @Override - public void detachFrom() { - // TODO Auto-generated method stub - - } - - @Override - public long getSize() { - return volumeInfo.getSize(); - } - - @Override - public DiskFormat getDiskType() { - return null; - } - - @Override - public VolumeType getType() { - return null; - } - - @Override - public StorageEntity getDataStore() { - return new PrimaryDataStoreEntityImpl((PrimaryDataStoreInfo) volumeInfo.getDataStore()); - } - - @Override - public void destroy() { - /* - * AsyncCallFuture future = - * vs.deleteVolumeAsync(volumeInfo); try { result = future.get(); if - * (!result.isSuccess()) { throw new - * CloudRuntimeException("Failed to create volume:" + - * result.getResult()); } } catch (InterruptedException e) { throw new - * CloudRuntimeException("wait to delete volume info failed", e); } - * catch (ExecutionException e) { throw new - * CloudRuntimeException("wait to delete volume failed", e); } - */ - } - - @Override - public Map getDetails() { - // TODO Auto-generated method stub - return null; - } - - @Override - public void addDetail(String name, String value) { - // TODO Auto-generated method stub - - } - - @Override - public void delDetail(String name, String value) { - // TODO Auto-generated method stub - - } - - @Override - public void updateDetail(String name, String value) { - // TODO Auto-generated method stub - - } - -} diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index 963015c7945..e799098bbb4 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -451,6 +451,47 @@ public class VolumeObject implements VolumeInfo { } + public void incRefCount() { + if (this.dataStore == null) { + return; + } + + if (this.dataStore.getRole() == DataStoreRole.Image || + this.dataStore.getRole() == DataStoreRole.ImageCache) { + VolumeDataStoreVO store = volumeStoreDao.findById(this.dataStore.getId()); + store.incrRefCnt(); + store.setLastUpdated(new Date()); + volumeStoreDao.update(store.getId(), store); + } + } + + @Override + public void decRefCount() { + if (this.dataStore == null) { + return; + } + if (this.dataStore.getRole() == DataStoreRole.Image || + this.dataStore.getRole() == DataStoreRole.ImageCache) { + VolumeDataStoreVO store = volumeStoreDao.findById(this.dataStore.getId()); + store.decrRefCnt(); + store.setLastUpdated(new Date()); + volumeStoreDao.update(store.getId(), store); + } + } + + @Override + public Long getRefCount() { + if (this.dataStore == null) { + return null; + } + if (this.dataStore.getRole() == DataStoreRole.Image || + this.dataStore.getRole() == DataStoreRole.ImageCache) { + VolumeDataStoreVO store = volumeStoreDao.findById(this.dataStore.getId()); + return store.getRefCnt(); + } + return null; + } + @Override public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer) { try { diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index 7d5b7a2937c..1d36f938fdf 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -120,9 +120,6 @@ public class VolumeServiceImpl implements VolumeService { private final DataObject volume; private final AsyncCallFuture future; - /** - * @param callback - */ public CreateVolumeContext(AsyncCompletionCallback callback, DataObject volume, AsyncCallFuture future) { super(callback); @@ -178,9 +175,6 @@ public class VolumeServiceImpl implements VolumeService { private final VolumeObject volume; private final AsyncCallFuture future; - /** - * @param callback - */ public DeleteVolumeContext(AsyncCompletionCallback callback, VolumeObject volume, AsyncCallFuture future) { super(callback); @@ -266,17 +260,7 @@ public class VolumeServiceImpl implements VolumeService { @Override public VolumeEntity getVolumeEntity(long volumeId) { - VolumeVO vo = volDao.findById(volumeId); - if (vo == null) { - return null; - } - - if (vo.getPoolId() == null) { - return new VolumeEntityImpl(VolumeObject.getVolumeObject(null, vo), this); - } else { - PrimaryDataStore dataStore = dataStoreMgr.getPrimaryDataStore(vo.getPoolId()); - return new VolumeEntityImpl(dataStore.getVolume(volumeId), this); - } + return null; } class CreateBaseImageContext extends AsyncRpcConext { @@ -315,15 +299,6 @@ public class VolumeServiceImpl implements VolumeService { } - static class CreateBaseImageResult extends CommandResult { - final TemplateInfo template; - - public CreateBaseImageResult(TemplateInfo template) { - super(); - this.template = template; - } - } - private TemplateInfo waitForTemplateDownloaded(PrimaryDataStore store, TemplateInfo template) { int storagePoolMaxWaitSeconds = NumbersUtil.parseInt( configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600); @@ -571,9 +546,6 @@ public class VolumeServiceImpl implements VolumeService { final VolumeInfo destVolume; final AsyncCallFuture future; - /** - * @param callback - */ public CopyVolumeContext(AsyncCompletionCallback callback, AsyncCallFuture future, VolumeInfo srcVolume, VolumeInfo destVolume, DataStore destStore) { super(callback); @@ -845,9 +817,6 @@ public class VolumeServiceImpl implements VolumeService { final Map volumeToPool; final AsyncCallFuture future; - /** - * @param callback - */ public MigrateVmWithVolumesContext(AsyncCompletionCallback callback, AsyncCallFuture future, Map volumeToPool) { super(callback); diff --git a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java index 7ff56f6582a..7b30575c8d1 100644 --- a/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackImageStoreLifeCycleImpl.java @@ -124,50 +124,32 @@ public class CloudStackImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Override public boolean attachCluster(DataStore store, ClusterScope scope) { - // TODO Auto-generated method stub return false; } @Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { - // TODO Auto-generated method stub return false; } @Override public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean dettach() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean unmanaged() { - // TODO Auto-generated method stub return false; } @Override public boolean maintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean cancelMaintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean deleteDataStore(DataStore store) { - // TODO Auto-generated method stub return false; } } diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java index 6965a152041..2630d137863 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/lifecycle/S3ImageStoreLifeCycleImpl.java @@ -53,8 +53,6 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { ImageStoreHelper imageStoreHelper; @Inject ImageStoreProviderManager imageStoreMgr; - @Inject - S3Manager _s3Mgr; protected List _discoverers; @@ -83,12 +81,6 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { s_logger.info("Trying to add a S3 store in data center " + dcId); - /* - * try{ // verify S3 parameters _s3Mgr.verifyS3Fields(details); } catch - * (DiscoveryException ex){ throw new - * InvalidParameterValueException("failed to verify S3 parameters!"); } - */ - Map imageStoreParameters = new HashMap(); imageStoreParameters.put("name", name); imageStoreParameters.put("zoneId", dcId); @@ -113,51 +105,31 @@ public class S3ImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Override public boolean attachCluster(DataStore store, ClusterScope scope) { - // TODO Auto-generated method stub return false; } @Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { - // TODO Auto-generated method stub return false; } - - @Override public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean dettach() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean unmanaged() { - // TODO Auto-generated method stub return false; } @Override public boolean maintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean cancelMaintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean deleteDataStore(DataStore store) { - // TODO Auto-generated method stub return false; } } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java index 2dae3c84bc5..44f94f39ee4 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/driver/SampleImageStoreDriverImpl.java @@ -37,15 +37,12 @@ public class SampleImageStoreDriverImpl extends BaseImageStoreDriverImpl { public SampleImageStoreDriverImpl() { } - @Override public DataStoreTO getStoreTO(DataStore store) { // TODO Auto-generated method stub return null; } - - @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { // TODO Auto-generated method stub diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java index c7e48018eaf..e4df6f55f3a 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SampleImageStoreLifeCycleImpl.java @@ -52,49 +52,31 @@ public class SampleImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Override public boolean attachCluster(DataStore store, ClusterScope scope) { - // TODO Auto-generated method stub return false; } @Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { - // TODO Auto-generated method stub return false; } @Override public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisor) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean dettach() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean unmanaged() { - // TODO Auto-generated method stub return false; } @Override public boolean maintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean cancelMaintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean deleteDataStore(DataStore store) { - // TODO Auto-generated method stub return false; } } diff --git a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java index c0c55d667d1..c52e96e0c93 100644 --- a/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java +++ b/plugins/storage/image/sample/src/org/apache/cloudstack/storage/datastore/provider/SampleImageStoreProviderImpl.java @@ -44,8 +44,6 @@ public class SampleImageStoreProviderImpl implements ImageStoreProvider { protected ImageStoreDriver driver; @Inject ImageStoreProviderManager storeMgr; - long id; - String uuid; @Override public DataStoreLifeCycle getDataStoreLifeCycle() { diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index bd5a14a277a..d6d6cd283f1 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -39,7 +39,6 @@ public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl { @Inject ImageStoreDetailsDao _imageStoreDetailsDao; - @Override public DataStoreTO getStoreTO(DataStore store) { ImageStoreImpl imgStore = (ImageStoreImpl) store; @@ -48,11 +47,9 @@ public class SwiftImageStoreDriverImpl extends BaseImageStoreDriverImpl { details.get(ApiConstants.USERNAME), details.get(ApiConstants.KEY)); } - @Override public String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format) { throw new UnsupportedServiceException("Extract entity url is not yet supported for Swift image store provider"); } - } diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java index 38e20073491..4256cc2cc7b 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/lifecycle/SwiftImageStoreLifeCycleImpl.java @@ -16,12 +16,11 @@ // under the License. package org.apache.cloudstack.storage.datastore.lifecycle; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; - +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.resource.ResourceManager; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.ScopeType; import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; @@ -33,12 +32,9 @@ import org.apache.cloudstack.storage.image.datastore.ImageStoreProviderManager; import org.apache.cloudstack.storage.image.store.lifecycle.ImageStoreLifeCycle; import org.apache.log4j.Logger; -import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.resource.Discoverer; -import com.cloud.resource.ResourceManager; -import com.cloud.storage.DataStoreRole; -import com.cloud.storage.ScopeType; +import javax.inject.Inject; +import java.util.HashMap; +import java.util.Map; public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @@ -52,16 +48,6 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Inject ImageStoreProviderManager imageStoreMgr; - protected List _discoverers; - - public List getDiscoverers() { - return _discoverers; - } - - public void setDiscoverers(List _discoverers) { - this._discoverers = _discoverers; - } - public SwiftImageStoreLifeCycleImpl() { } @@ -99,50 +85,32 @@ public class SwiftImageStoreLifeCycleImpl implements ImageStoreLifeCycle { @Override public boolean attachCluster(DataStore store, ClusterScope scope) { - // TODO Auto-generated method stub return false; } @Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { - // TODO Auto-generated method stub return false; } @Override public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean dettach() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean unmanaged() { - // TODO Auto-generated method stub return false; } @Override public boolean maintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean cancelMaintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean deleteDataStore(DataStore store) { - // TODO Auto-generated method stub return false; } } diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java index 4c2f3894ef2..8d7c965ee07 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/driver/CloudStackPrimaryDataStoreDriverImpl.java @@ -18,27 +18,6 @@ */ package org.apache.cloudstack.storage.datastore.driver; -import java.util.Set; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -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.command.CommandResult; -import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.command.DeleteCommand; -import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.volume.VolumeObject; -import org.apache.log4j.Logger; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.ResizeVolumeAnswer; import com.cloud.agent.api.storage.ResizeVolumeCommand; @@ -58,6 +37,16 @@ import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.vm.dao.VMInstanceDao; +import org.apache.cloudstack.engine.subsystem.api.storage.*; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.command.DeleteCommand; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.volume.VolumeObject; +import org.apache.log4j.Logger; + +import javax.inject.Inject; public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { private static final Logger s_logger = Logger.getLogger(CloudStackPrimaryDataStoreDriverImpl.class); @@ -84,12 +73,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Inject EndPointSelector epSelector; - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } - @Override public DataTO getTO(DataObject data) { return null; @@ -97,19 +80,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Override public DataStoreTO getStoreTO(DataStore store) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub return null; } @@ -126,7 +96,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub String errMsg = null; Answer answer = null; if (data.getType() == DataObjectType.VOLUME) { @@ -168,13 +137,10 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Override public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub return false; } @@ -205,8 +171,6 @@ public class CloudStackPrimaryDataStoreDriverImpl implements PrimaryDataStoreDri @Override public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override diff --git a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java index 38dd5a9b276..2e0ff66baa1 100644 --- a/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/default/src/org/apache/cloudstack/storage/datastore/lifecycle/CloudStackPrimaryDataStoreLifeCycleImpl.java @@ -417,18 +417,6 @@ public class CloudStackPrimaryDataStoreLifeCycleImpl implements PrimaryDataStore return true; } - @Override - public boolean dettach() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean unmanaged() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean maintain(DataStore dataStore) { storagePoolAutmation.maintain(dataStore); diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java index ad506d1793c..643c9334964 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/driver/SamplePrimaryDataStoreDriverImpl.java @@ -16,35 +16,20 @@ // under the License. package org.apache.cloudstack.storage.datastore.driver; -import java.net.URISyntaxException; -import java.util.Set; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; -import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; -import org.apache.cloudstack.framework.async.AsyncCompletionCallback; -import org.apache.cloudstack.framework.async.AsyncRpcConext; -import org.apache.cloudstack.storage.command.CommandResult; -import org.apache.cloudstack.storage.command.CreateObjectAnswer; -import org.apache.cloudstack.storage.command.CreateObjectCommand; -import org.apache.cloudstack.storage.datastore.DataObjectManager; -import org.apache.log4j.Logger; - import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.DataTO; import com.cloud.storage.dao.StoragePoolHostDao; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.storage.encoding.DecodedDataObject; -import com.cloud.utils.storage.encoding.Decoder; +import org.apache.cloudstack.engine.subsystem.api.storage.*; +import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher; +import org.apache.cloudstack.framework.async.AsyncCompletionCallback; +import org.apache.cloudstack.framework.async.AsyncRpcConext; +import org.apache.cloudstack.storage.command.CommandResult; +import org.apache.cloudstack.storage.command.CreateObjectCommand; +import org.apache.cloudstack.storage.datastore.DataObjectManager; +import org.apache.log4j.Logger; + +import javax.inject.Inject; public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver { private static final Logger s_logger = Logger.getLogger(SamplePrimaryDataStoreDriverImpl.class); @@ -66,25 +51,15 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver @Override public DataStoreTO getStoreTO(DataStore store) { - // TODO Auto-generated method stub return null; } private class CreateVolumeContext extends AsyncRpcConext { private final DataObject volume; - - /** - * @param callback - */ public CreateVolumeContext(AsyncCompletionCallback callback, DataObject volume) { super(callback); this.volume = volume; } - - public DataObject getVolume() { - return this.volume; - } - } public Void createAsyncCallback(AsyncCallbackDispatcher callback, @@ -182,75 +157,25 @@ public class SamplePrimaryDataStoreDriverImpl implements PrimaryDataStoreDriver ep.sendMessageAsync(createCmd, caller); } - @Override - public String grantAccess(DataObject object, EndPoint ep) { - // StoragePoolHostVO poolHost = - // storeHostDao.findByPoolHost(object.getDataStore().getId(), - // ep.getId()); - - String uri = object.getUri(); - try { - DecodedDataObject obj = Decoder.decode(uri); - if (obj.getPath() == null) { - // create an obj - EndPoint newEp = selector.select(object); - CreateObjectCommand createCmd = new CreateObjectCommand(null); - CreateObjectAnswer answer = (CreateObjectAnswer) ep.sendMessage(createCmd); - if (answer.getResult()) { - // dataObjMgr.update(object, answer.getPath(), - // answer.getSize()); - } else { - s_logger.debug("failed to create object" + answer.getDetails()); - throw new CloudRuntimeException("failed to create object" + answer.getDetails()); - } - } - - return object.getUri(); - } catch (URISyntaxException e) { - throw new CloudRuntimeException("uri parsed error", e); - } - } - - @Override - public boolean revokeAccess(DataObject vol, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub - return null; - } - @Override public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub return false; } @Override public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } } diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java index 7ee8565e7e7..92538ad5f4b 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/lifecycle/SamplePrimaryDataStoreLifeCycleImpl.java @@ -18,18 +18,12 @@ */ package org.apache.cloudstack.storage.datastore.lifecycle; -import java.util.List; -import java.util.Map; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPointSelector; -import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreLifeCycle; -import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope; +import com.cloud.agent.api.StoragePoolInfo; +import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; +import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.StoragePoolStatus; +import org.apache.cloudstack.engine.subsystem.api.storage.*; import org.apache.cloudstack.storage.command.AttachPrimaryDataStoreCmd; import org.apache.cloudstack.storage.command.CreatePrimaryDataStoreCmd; import org.apache.cloudstack.storage.datastore.PrimaryDataStoreProviderManager; @@ -37,11 +31,9 @@ import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; import org.apache.cloudstack.storage.volume.datastore.PrimaryDataStoreHelper; -import com.cloud.agent.api.StoragePoolInfo; -import com.cloud.host.HostVO; -import com.cloud.host.dao.HostDao; -import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.storage.StoragePoolStatus; +import javax.inject.Inject; +import java.util.List; +import java.util.Map; public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLifeCycle { @Inject @@ -102,45 +94,28 @@ public class SamplePrimaryDataStoreLifeCycleImpl implements PrimaryDataStoreLife return true; } - @Override - public boolean dettach() { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean unmanaged() { - // TODO Auto-generated method stub - return false; - } - @Override public boolean attachZone(DataStore dataStore, ZoneScope scope, HypervisorType hypervisorType) { - // TODO Auto-generated method stub return false; } @Override public boolean attachHost(DataStore store, HostScope scope, StoragePoolInfo existingInfo) { - // TODO Auto-generated method stub return false; } @Override public boolean maintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean cancelMaintain(DataStore store) { - // TODO Auto-generated method stub return false; } @Override public boolean deleteDataStore(DataStore store) { - // TODO Auto-generated method stub return false; } diff --git a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java index 87088214dbc..79ffc8fe4a1 100644 --- a/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java +++ b/plugins/storage/volume/sample/src/org/apache/cloudstack/storage/datastore/provider/SamplePrimaryDatastoreProviderImpl.java @@ -40,8 +40,6 @@ public class SamplePrimaryDatastoreProviderImpl implements PrimaryDataStoreProvi PrimaryDataStoreProviderManager storeMgr; protected DataStoreLifeCycle lifecycle; - protected String uuid; - protected long id; @Override public String getName() { diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java index a296bab834a..960378c2821 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidfirePrimaryDataStoreDriver.java @@ -16,29 +16,14 @@ // under the License. package org.apache.cloudstack.storage.datastore.driver; -import java.util.Set; - -import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; -import org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult; -import org.apache.cloudstack.engine.subsystem.api.storage.DataObject; -import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; -import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreDriver; -import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import org.apache.cloudstack.engine.subsystem.api.storage.*; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.storage.command.CommandResult; -import com.cloud.agent.api.to.DataStoreTO; -import com.cloud.agent.api.to.DataTO; - public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { - @Override - public String grantAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return null; - } - @Override public DataTO getTO(DataObject data) { return null; @@ -46,62 +31,36 @@ public class SolidfirePrimaryDataStoreDriver implements PrimaryDataStoreDriver { @Override public DataStoreTO getStoreTO(DataStore store) { - // TODO Auto-generated method stub - return null; - } - - @Override - public boolean revokeAccess(DataObject data, EndPoint ep) { - // TODO Auto-generated method stub - return false; - } - - @Override - public Set listObjects(DataStore store) { - // TODO Auto-generated method stub return null; } @Override public void createAsync(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public void deleteAsync(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public void copyAsync(DataObject srcdata, DataObject destData, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public boolean canCopy(DataObject srcData, DataObject destData) { - // TODO Auto-generated method stub return false; } @Override public void revertSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public void resize(DataObject data, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } @Override public void takeSnapshot(SnapshotInfo snapshot, AsyncCompletionCallback callback) { - // TODO Auto-generated method stub - } } diff --git a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java index 03f241ef132..2965e8ff58e 100644 --- a/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java +++ b/plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/provider/SolidfirePrimaryDataStoreProvider.java @@ -29,11 +29,6 @@ import org.springframework.stereotype.Component; public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvider { private final String name = "Solidfire Primary Data Store Provider"; - public SolidfirePrimaryDataStoreProvider() { - - // TODO Auto-generated constructor stub - } - @Override public String getName() { return name; @@ -41,31 +36,26 @@ public class SolidfirePrimaryDataStoreProvider implements PrimaryDataStoreProvid @Override public DataStoreLifeCycle getDataStoreLifeCycle() { - // TODO Auto-generated method stub return null; } @Override public DataStoreDriver getDataStoreDriver() { - // TODO Auto-generated method stub return null; } @Override public HypervisorHostListener getHostListener() { - // TODO Auto-generated method stub return null; } @Override public boolean configure(Map params) { - // TODO Auto-generated method stub return false; } @Override public Set getTypes() { - // TODO Auto-generated method stub return null; } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 5ee0fad8643..6bad4176da5 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -72,7 +72,10 @@ public enum Config { StorageOverprovisioningFactor("Storage", StoragePoolAllocator.class, String.class, "storage.overprovisioning.factor", "2", "Used for storage overprovisioning calculation; available storage will be (actualStorageSize * storage.overprovisioning.factor)", null, ConfigurationParameterScope.zone.toString()), StorageStatsInterval("Storage", ManagementServer.class, String.class, "storage.stats.interval", "60000", "The interval (in milliseconds) when storage stats (per host) are retrieved from agents.", null), MaxVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.size", "2000", "The maximum size for a volume (in GB).", null), - MaxUploadVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.upload.size", "500", "The maximum size for a uploaded volume(in GB).", null), + StorageCacheReplacementLRUTimeInterval("Storage", ManagementServer.class, Integer.class, "storage.cache.replacement.lru.interval", "30", "time interval for unsed data on cache storage (in days).", null), + StorageCacheReplacementEnabled("Storage", ManagementServer.class, Boolean.class, "storage.cache.replacement.enabled", "true", "enable or disable cache storage replacement algorithm.", null), + StorageCacheReplacementInterval("Storage", ManagementServer.class, Integer.class, "storage.cache.replacement.interval", "86400", "time interval between cache replacement threads (in seconds).", null), + MaxUploadVolumeSize("Storage", ManagementServer.class, Integer.class, "storage.max.volume.upload.size", "500", "The maximum size for a uploaded volume(in GB).", null), TotalRetries("Storage", AgentManager.class, Integer.class, "total.retries", "4", "The number of times each command sent to a host should be retried in case of failure.", null), StoragePoolMaxWaitSeconds("Storage", ManagementServer.class, Integer.class, "storage.pool.max.waitseconds", "3600", "Timeout (in seconds) to synchronize storage pool operations.", 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), diff --git a/server/src/com/cloud/server/StatsCollector.java b/server/src/com/cloud/server/StatsCollector.java index e5104358503..0d7fc3d65ee 100755 --- a/server/src/com/cloud/server/StatsCollector.java +++ b/server/src/com/cloud/server/StatsCollector.java @@ -185,13 +185,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc _executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval, vmDiskStatsInterval, TimeUnit.SECONDS); } - // -1 means we don't even start this thread to pick up any data. - if (volumeStatsInterval > 0) { - _executor.scheduleWithFixedDelay(new VolumeCollector(), 15000L, volumeStatsInterval, TimeUnit.MILLISECONDS); - } else { - s_logger.info("Disabling volume stats collector"); - } - //Schedule disk stats update task _diskStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DiskStatsUpdater")); String aggregationRange = configs.get("usage.stats.job.aggregation.range"); @@ -548,13 +541,6 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc if (answer != null && answer.getResult()) { storageStats.put(storeId, (StorageStats)answer); s_logger.trace("HostId: "+storeId+ " Used: " + ((StorageStats)answer).getByteUsed() + " Total Available: " + ((StorageStats)answer).getCapacityBytes()); - //Seems like we have dynamically updated the sec. storage as prev. size and the current do not match - if (_storageStats.get(storeId)!=null && - _storageStats.get(storeId).getCapacityBytes() != ((StorageStats)answer).getCapacityBytes()){ - ImageStoreVO imgStore = _imageStoreDao.findById(storeId); - imgStore.setTotalSize(((StorageStats)answer).getCapacityBytes()); - _imageStoreDao.update(storeId, imgStore); - } } } _storageStats = storageStats; @@ -603,79 +589,4 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc public StorageStats getStoragePoolStats(long id) { return _storagePoolStats.get(id); } - - class VolumeCollector implements Runnable { - @Override - public void run() { - try { - List volumes = _volsDao.listAll(); - Map> commandsByPool = new HashMap>(); - - for (VolumeVO volume : volumes) { - List commands = commandsByPool.get(volume.getPoolId()); - if (commands == null) { - commands = new ArrayList(); - commandsByPool.put(volume.getPoolId(), commands); - } - VolumeCommand vCommand = new VolumeCommand(); - vCommand.volumeId = volume.getId(); - vCommand.command = new GetFileStatsCommand(volume); - commands.add(vCommand); - } - ConcurrentHashMap volumeStats = new ConcurrentHashMap(); - for (Iterator iter = commandsByPool.keySet().iterator(); iter.hasNext();) { - Long poolId = iter.next(); - if(poolId != null) { - List commandsList = commandsByPool.get(poolId); - - long[] volumeIdArray = new long[commandsList.size()]; - Commands commands = new Commands(OnError.Continue); - for (int i = 0; i < commandsList.size(); i++) { - VolumeCommand vCommand = commandsList.get(i); - volumeIdArray[i] = vCommand.volumeId; - commands.addCommand(vCommand.command); - } - - List poolhosts = _storagePoolHostDao.listByPoolId(poolId); - for(StoragePoolHostVO poolhost : poolhosts) { - Answer[] answers = _agentMgr.send(poolhost.getHostId(), commands); - if (answers != null) { - long totalBytes = 0L; - for (int i = 0; i < answers.length; i++) { - if (answers[i].getResult()) { - VolumeStats vStats = (VolumeStats)answers[i]; - volumeStats.put(volumeIdArray[i], vStats); - totalBytes += vStats.getBytesUsed(); - } - } - break; - } - } - } - } - - // We replace the existing volumeStats so that it does not grow with no bounds - _volumeStats = volumeStats; - } catch (AgentUnavailableException e) { - s_logger.debug(e.getMessage()); - } catch (Throwable t) { - s_logger.error("Error trying to retrieve volume stats", t); - } - } - } - - private class VolumeCommand { - public long volumeId; - public GetFileStatsCommand command; - } - - public VolumeStats[] getVolumeStats(long[] ids) { - VolumeStats[] stats = new VolumeStats[ids.length]; - if (volumeStatsInterval > 0) { - for (int i = 0; i < ids.length; i++) { - stats[i] = _volumeStats.get(ids[i]); - } - } - return stats; - } } diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index 387e909d347..a8a133f1263 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -37,6 +37,7 @@ ALTER TABLE `cloud`.`load_balancer_vm_map` ADD state VARCHAR(40) NULL COMMENT 's alter table storage_pool add hypervisor varchar(32); alter table storage_pool change storage_provider_id storage_provider_name varchar(255); +alter table storage_pool change available_bytes used_bytes bigint unsigned; -- alter table template_host_ref add state varchar(255); -- alter table template_host_ref add update_count bigint unsigned; -- alter table template_host_ref add updated datetime; @@ -88,7 +89,8 @@ CREATE TABLE `cloud`.`image_store` ( `parent` varchar(255) COMMENT 'parent path for the storage server', `created` datetime COMMENT 'date the image store first signed on', `removed` datetime COMMENT 'date removed if not null', - `total_size` bigint unsigned COMMENT 'storage statistics', + `total_size` bigint unsigned COMMENT 'storage total size statistics', + `used_bytes` bigint unsigned COMMENT 'storage available bytes statistics', PRIMARY KEY(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -149,6 +151,7 @@ CREATE TABLE `cloud`.`template_store_ref` ( `destroyed` tinyint(1) COMMENT 'indicates whether the template_store entry was destroyed by the user or not', `is_copy` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'indicates whether this was copied ', `update_count` bigint unsigned, + `ref_cnt` bigint unsigned, `updated` datetime, PRIMARY KEY (`id`), -- CONSTRAINT `fk_template_store_ref__store_id` FOREIGN KEY `fk_template_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, @@ -183,6 +186,7 @@ CREATE TABLE `cloud`.`snapshot_store_ref` ( `state` varchar(255) NOT NULL, -- `removed` datetime COMMENT 'date removed if not null', `update_count` bigint unsigned, + `ref_cnt` bigint unsigned, `updated` datetime, PRIMARY KEY (`id`), INDEX `i_snapshot_store_ref__store_id`(`store_id`), @@ -210,6 +214,7 @@ CREATE TABLE `cloud`.`volume_store_ref` ( `state` varchar(255) NOT NULL, `destroyed` tinyint(1) COMMENT 'indicates whether the volume_host entry was destroyed by the user or not', `update_count` bigint unsigned, + `ref_cnt` bigint unsigned, `updated` datetime, PRIMARY KEY (`id`), CONSTRAINT `fk_volume_store_ref__store_id` FOREIGN KEY `fk_volume_store_ref__store_id` (`store_id`) REFERENCES `image_store` (`id`) ON DELETE CASCADE, diff --git a/test/pom.xml b/test/pom.xml index d4b88326fa2..92e62734ac4 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -75,7 +75,7 @@ compile - src + test test From c2da4eac89d932ce1bf15440c4ae2095e123d8b8 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 14 Jun 2013 17:24:31 -0700 Subject: [PATCH 293/303] fix NPE for cache ref cnt --- client/tomcatconf/applicationContext.xml.in | 1 - .../storage/image/store/TemplateObject.java | 50 +++++----- .../storage/snapshot/SnapshotObject.java | 20 ++-- .../storage/volume/VolumeObject.java | 16 ++- .../kvm/storage/KVMStorageProcessor.java | 2 - .../discoverer/LibvirtServerDiscoverer.java | 97 +++++++++++-------- 6 files changed, 97 insertions(+), 89 deletions(-) diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in index 181219a611f..2a746a9cd05 100644 --- a/client/tomcatconf/applicationContext.xml.in +++ b/client/tomcatconf/applicationContext.xml.in @@ -317,7 +317,6 @@ - diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index 5ab52de8500..74a7d43e00b 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -44,8 +44,8 @@ import com.cloud.storage.DataStoreRole; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.TemplateType; import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; +import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.utils.component.ComponentContext; @@ -122,12 +122,12 @@ public class TemplateObject implements TemplateInfo { } /* - * + * * // If the template that was passed into this allocator is not * installed in the storage pool, // add 3 * (template size on secondary * storage) to the running total VMTemplateHostVO templateHostVO = * _storageMgr.findVmTemplateHost(templateForVmCreation.getId(), null); - * + * * if (templateHostVO == null) { VMTemplateSwiftVO templateSwiftVO = * _swiftMgr.findByTmpltId(templateForVmCreation.getId()); if * (templateSwiftVO != null) { long templateSize = @@ -152,12 +152,14 @@ public class TemplateObject implements TemplateInfo { return this.imageVO.getFormat(); } -// public boolean stateTransit(TemplateEvent e) throws NoTransitionException { -// this.imageVO = imageDao.findById(this.imageVO.getId()); -// boolean result = imageMgr.getStateMachine().transitTo(this.imageVO, e, null, imageDao); -// this.imageVO = imageDao.findById(this.imageVO.getId()); -// return result; -// } + // public boolean stateTransit(TemplateEvent e) throws NoTransitionException + // { + // this.imageVO = imageDao.findById(this.imageVO.getId()); + // boolean result = imageMgr.getStateMachine().transitTo(this.imageVO, e, + // null, imageDao); + // this.imageVO = imageDao.findById(this.imageVO.getId()); + // return result; + // } @Override public void processEvent(Event event) { @@ -175,9 +177,10 @@ public class TemplateObject implements TemplateInfo { templEvent = TemplateEvent.OperationFailed; } -// if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { -// this.stateTransit(templEvent); -// } + // if (templEvent != null && this.getDataStore().getRole() == + // DataStoreRole.Image) { + // this.stateTransit(templEvent); + // } } objectInStoreMgr.update(this, event); @@ -238,9 +241,10 @@ public class TemplateObject implements TemplateInfo { templEvent = TemplateEvent.OperationFailed; } -// if (templEvent != null && this.getDataStore().getRole() == DataStoreRole.Image) { -// this.stateTransit(templEvent); -// } + // if (templEvent != null && this.getDataStore().getRole() == + // DataStoreRole.Image) { + // this.stateTransit(templEvent); + // } } objectInStoreMgr.update(this, event); } catch (NoTransitionException e) { @@ -264,9 +268,8 @@ public class TemplateObject implements TemplateInfo { return; } - if (this.dataStore.getRole() == DataStoreRole.Image || - this.dataStore.getRole() == DataStoreRole.ImageCache) { - TemplateDataStoreVO store = templateStoreDao.findById(this.dataStore.getId()); + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), this.getId()); store.incrRefCnt(); store.setLastUpdated(new Date()); templateStoreDao.update(store.getId(), store); @@ -278,9 +281,8 @@ public class TemplateObject implements TemplateInfo { if (this.dataStore == null) { return; } - if (this.dataStore.getRole() == DataStoreRole.Image || - this.dataStore.getRole() == DataStoreRole.ImageCache) { - TemplateDataStoreVO store = templateStoreDao.findById(this.dataStore.getId()); + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), this.getId()); store.decrRefCnt(); store.setLastUpdated(new Date()); templateStoreDao.update(store.getId(), store); @@ -292,9 +294,8 @@ public class TemplateObject implements TemplateInfo { if (this.dataStore == null) { return null; } - if (this.dataStore.getRole() == DataStoreRole.Image || - this.dataStore.getRole() == DataStoreRole.ImageCache) { - TemplateDataStoreVO store = templateStoreDao.findById(this.dataStore.getId()); + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + TemplateDataStoreVO store = templateStoreDao.findByStoreTemplate(dataStore.getId(), this.getId()); return store.getRefCnt(); } return null; @@ -442,5 +443,4 @@ public class TemplateObject implements TemplateInfo { return true; } - } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index 03104882706..1cba96efd40 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -22,7 +22,6 @@ import java.util.Date; import javax.inject.Inject; -import com.cloud.storage.DataStoreRole; 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.SnapshotDataFactory; @@ -41,6 +40,7 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.to.DataObjectType; import com.cloud.agent.api.to.DataTO; import com.cloud.hypervisor.Hypervisor.HypervisorType; +import com.cloud.storage.DataStoreRole; import com.cloud.storage.Snapshot; import com.cloud.storage.SnapshotVO; import com.cloud.storage.dao.SnapshotDao; @@ -279,9 +279,9 @@ public class SnapshotObject implements SnapshotInfo { return; } - if (this.store.getRole() == DataStoreRole.Image || - this.store.getRole() == DataStoreRole.ImageCache) { - SnapshotDataStoreVO store = snapshotStoreDao.findById(this.store.getId()); + if (this.store.getRole() == DataStoreRole.Image || this.store.getRole() == DataStoreRole.ImageCache) { + SnapshotDataStoreVO store = snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), this.store.getId(), + this.getId()); store.incrRefCnt(); store.setLastUpdated(new Date()); snapshotStoreDao.update(store.getId(), store); @@ -293,9 +293,9 @@ public class SnapshotObject implements SnapshotInfo { if (this.store == null) { return; } - if (this.store.getRole() == DataStoreRole.Image || - this.store.getRole() == DataStoreRole.ImageCache) { - SnapshotDataStoreVO store = snapshotStoreDao.findById(this.store.getId()); + if (this.store.getRole() == DataStoreRole.Image || this.store.getRole() == DataStoreRole.ImageCache) { + SnapshotDataStoreVO store = snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), this.store.getId(), + this.getId()); store.decrRefCnt(); store.setLastUpdated(new Date()); snapshotStoreDao.update(store.getId(), store); @@ -307,9 +307,9 @@ public class SnapshotObject implements SnapshotInfo { if (this.store == null) { return null; } - if (this.store.getRole() == DataStoreRole.Image || - this.store.getRole() == DataStoreRole.ImageCache) { - SnapshotDataStoreVO store = snapshotStoreDao.findById(this.store.getId()); + if (this.store.getRole() == DataStoreRole.Image || this.store.getRole() == DataStoreRole.ImageCache) { + SnapshotDataStoreVO store = snapshotStoreDao.findByStoreSnapshot(this.store.getRole(), this.store.getId(), + this.getId()); return store.getRefCnt(); } return null; diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index e799098bbb4..d689195957c 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -252,7 +252,6 @@ public class VolumeObject implements VolumeInfo { } } - @Override public String getName() { return this.volumeVO.getName(); @@ -456,9 +455,8 @@ public class VolumeObject implements VolumeInfo { return; } - if (this.dataStore.getRole() == DataStoreRole.Image || - this.dataStore.getRole() == DataStoreRole.ImageCache) { - VolumeDataStoreVO store = volumeStoreDao.findById(this.dataStore.getId()); + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); store.incrRefCnt(); store.setLastUpdated(new Date()); volumeStoreDao.update(store.getId(), store); @@ -470,9 +468,8 @@ public class VolumeObject implements VolumeInfo { if (this.dataStore == null) { return; } - if (this.dataStore.getRole() == DataStoreRole.Image || - this.dataStore.getRole() == DataStoreRole.ImageCache) { - VolumeDataStoreVO store = volumeStoreDao.findById(this.dataStore.getId()); + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); store.decrRefCnt(); store.setLastUpdated(new Date()); volumeStoreDao.update(store.getId(), store); @@ -484,9 +481,8 @@ public class VolumeObject implements VolumeInfo { if (this.dataStore == null) { return null; } - if (this.dataStore.getRole() == DataStoreRole.Image || - this.dataStore.getRole() == DataStoreRole.ImageCache) { - VolumeDataStoreVO store = volumeStoreDao.findById(this.dataStore.getId()); + if (this.dataStore.getRole() == DataStoreRole.Image || this.dataStore.getRole() == DataStoreRole.ImageCache) { + VolumeDataStoreVO store = volumeStoreDao.findByStoreVolume(this.dataStore.getId(), this.getId()); return store.getRefCnt(); } return null; diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index a03ac697a77..f0f916a411c 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -699,8 +699,6 @@ public class KVMStorageProcessor implements StorageProcessor { s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); return new AttachAnswer(e.toString()); } - - } @Override diff --git a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java index c92ff500b22..f59bdf370aa 100644 --- a/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java +++ b/server/src/com/cloud/hypervisor/kvm/discoverer/LibvirtServerDiscoverer.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -62,20 +61,26 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.utils.ssh.SSHCmdHelper; -public abstract class LibvirtServerDiscoverer extends DiscovererBase implements Discoverer, -Listener, ResourceStateAdapter { +public abstract class LibvirtServerDiscoverer extends DiscovererBase implements Discoverer, Listener, + ResourceStateAdapter { private static final Logger s_logger = Logger.getLogger(LibvirtServerDiscoverer.class); private String _hostIp; - private final int _waitTime = 5; /*wait for 5 minutes*/ + private final int _waitTime = 5; /* wait for 5 minutes */ private String _kvmPrivateNic; private String _kvmPublicNic; private String _kvmGuestNic; - @Inject HostDao _hostDao = null; - @Inject ClusterDao _clusterDao; - @Inject ResourceManager _resourceMgr; - @Inject AgentManager _agentMgr; - @Inject ConfigurationDao _configDao; - @Inject NetworkModel _networkMgr; + @Inject + HostDao _hostDao = null; + @Inject + ClusterDao _clusterDao; + @Inject + ResourceManager _resourceMgr; + @Inject + AgentManager _agentMgr; + @Inject + ConfigurationDao _configDao; + @Inject + NetworkModel _networkMgr; public abstract Hypervisor.HypervisorType getHypervisorType(); @@ -92,8 +97,7 @@ Listener, ResourceStateAdapter { } @Override - public AgentControlAnswer processControlCommand(long agentId, - AgentControlCommand cmd) { + public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { // TODO Auto-generated method stub return null; } @@ -127,14 +131,13 @@ Listener, ResourceStateAdapter { } @Override - public Map> find(long dcId, - Long podId, Long clusterId, URI uri, String username, - String password, List hostTags) throws DiscoveryException { + public Map> find(long dcId, Long podId, Long clusterId, URI uri, + String username, String password, List hostTags) throws DiscoveryException { ClusterVO cluster = _clusterDao.findById(clusterId); - if(cluster == null || cluster.getHypervisorType() != getHypervisorType()) { - if(s_logger.isInfoEnabled()) - s_logger.info("invalid cluster id or cluster is not for " + getHypervisorType() + " hypervisors"); + if (cluster == null || cluster.getHypervisorType() != getHypervisorType()) { + if (s_logger.isInfoEnabled()) + s_logger.info("invalid cluster id or cluster is not for " + getHypervisorType() + " hypervisors"); return null; } @@ -153,11 +156,16 @@ Listener, ResourceStateAdapter { InetAddress ia = InetAddress.getByName(hostname); agentIp = ia.getHostAddress(); String guid = UUID.nameUUIDFromBytes(agentIp.getBytes()).toString(); - String guidWithTail = guid + "-LibvirtComputingResource";/*tail added by agent.java*/ + String guidWithTail = guid + "-LibvirtComputingResource";/* + * tail + * added by + * agent + * .java + */ if (_resourceMgr.findHostByGuid(guidWithTail) != null) { s_logger.debug("Skipping " + agentIp + " because " + guidWithTail + " is already in the database."); return null; - } + } sshConnection = new com.trilead.ssh2.Connection(agentIp, 22); @@ -172,7 +180,7 @@ Listener, ResourceStateAdapter { return null; } - List netInfos = _networkMgr.getPhysicalNetworkInfo(dcId, getHypervisorType()); + List netInfos = _networkMgr.getPhysicalNetworkInfo(dcId, getHypervisorType()); String kvmPrivateNic = null; String kvmPublicNic = null; String kvmGuestNic = null; @@ -193,7 +201,7 @@ Listener, ResourceStateAdapter { kvmPrivateNic = _kvmPrivateNic; kvmPublicNic = _kvmPublicNic; kvmGuestNic = _kvmGuestNic; - } + } if (kvmPublicNic == null) { kvmPublicNic = (kvmGuestNic != null) ? kvmGuestNic : kvmPrivateNic; @@ -207,7 +215,8 @@ Listener, ResourceStateAdapter { kvmGuestNic = (kvmPublicNic != null) ? kvmPublicNic : kvmPrivateNic; } - String parameters = " -m " + _hostIp + " -z " + dcId + " -p " + podId + " -c " + clusterId + " -g " + guid + " -a"; + String parameters = " -m " + _hostIp + " -z " + dcId + " -p " + podId + " -c " + clusterId + " -g " + guid + + " -a"; parameters += " --pubNic=" + kvmPublicNic; parameters += " --prvNic=" + kvmPrivateNic; @@ -220,8 +229,8 @@ Listener, ResourceStateAdapter { params.put("zone", Long.toString(dcId)); params.put("pod", Long.toString(podId)); - params.put("cluster", Long.toString(clusterId)); - params.put("guid", guid); + params.put("cluster", Long.toString(clusterId)); + params.put("guid", guid); params.put("agentIp", agentIp); kvmResource.configure("kvm agent", params); resources.put(kvmResource, details); @@ -238,16 +247,16 @@ Listener, ResourceStateAdapter { _clusterDao.update(clusterId, cluster); } - //save user name and password + // save user name and password _hostDao.loadDetails(connectedHost); Map hostDetails = connectedHost.getDetails(); hostDetails.put("password", password); hostDetails.put("username", username); _hostDao.saveDetails(connectedHost); return resources; - } catch (DiscoveredWithErrorException e){ + } catch (DiscoveredWithErrorException e) { throw e; - }catch (Exception e) { + } catch (Exception e) { String msg = " can't setup agent, due to " + e.toString() + " - " + e.getMessage(); s_logger.warn(msg); } finally { @@ -259,7 +268,7 @@ Listener, ResourceStateAdapter { } private HostVO waitForHostConnect(long dcId, long podId, long clusterId, String guid) { - for (int i = 0; i < _waitTime *2; i++) { + for (int i = 0; i < _waitTime * 2; i++) { List hosts = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.Routing, clusterId, podId, dcId); for (HostVO host : hosts) { if (host.getGuid().equalsIgnoreCase(guid)) { @@ -283,7 +292,8 @@ Listener, ResourceStateAdapter { @Override public boolean configure(String name, Map params) throws ConfigurationException { -// _setupAgentPath = Script.findScript(getPatchPath(), "setup_agent.sh"); + // _setupAgentPath = Script.findScript(getPatchPath(), + // "setup_agent.sh"); _kvmPrivateNic = _configDao.getValue(Config.KvmPrivateNetwork.key()); if (_kvmPrivateNic == null) { _kvmPrivateNic = "cloudbr0"; @@ -312,15 +322,14 @@ Listener, ResourceStateAdapter { } @Override - public void postDiscovery(List hosts, long msId) - throws DiscoveryException { + public void postDiscovery(List hosts, long msId) throws DiscoveryException { // TODO Auto-generated method stub } @Override public boolean matchHypervisor(String hypervisor) { // for backwards compatibility, if not supplied, always let to try it - if(hypervisor == null) + if (hypervisor == null) return true; return getHypervisorType().toString().equalsIgnoreCase(hypervisor); @@ -340,6 +349,11 @@ Listener, ResourceStateAdapter { /* KVM requires host are the same in cluster */ ClusterVO clusterVO = _clusterDao.findById(host.getClusterId()); + if (clusterVO == null) { + s_logger.debug("cannot find cluster: " + host.getClusterId()); + throw new IllegalArgumentException("cannot add host, due to can't find cluster: " + host.getClusterId()); + } + List hostsInCluster = _resourceMgr.listAllHostsInCluster(clusterVO.getId()); if (!hostsInCluster.isEmpty()) { HostVO oneHost = hostsInCluster.get(0); @@ -347,8 +361,9 @@ Listener, ResourceStateAdapter { String hostOsInCluster = oneHost.getDetail("Host.OS"); String hostOs = ssCmd.getHostDetails().get("Host.OS"); if (!hostOsInCluster.equalsIgnoreCase(hostOs)) { - throw new IllegalArgumentException("Can't add host: " + firstCmd.getPrivateIpAddress() + " with hostOS: " + hostOs + " into a cluster," - + "in which there are " + hostOsInCluster + " hosts added"); + throw new IllegalArgumentException("Can't add host: " + firstCmd.getPrivateIpAddress() + + " with hostOS: " + hostOs + " into a cluster," + "in which there are " + hostOsInCluster + + " hosts added"); } } @@ -358,17 +373,17 @@ Listener, ResourceStateAdapter { } @Override - public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map details, - List hostTags) { + public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, + Map details, List hostTags) { // TODO Auto-generated method stub return null; } @Override - public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) throws UnableDeleteHostException { - if (host.getType() != Host.Type.Routing || - (host.getHypervisorType() != HypervisorType.KVM && - host.getHypervisorType() != HypervisorType.LXC)) { + public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, boolean isForceDeleteStorage) + throws UnableDeleteHostException { + if (host.getType() != Host.Type.Routing + || (host.getHypervisorType() != HypervisorType.KVM && host.getHypervisorType() != HypervisorType.LXC)) { return null; } From 619ec12f61e65ad1f83d1c9b4951a8f8797b54dc Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 14 Jun 2013 17:35:53 -0700 Subject: [PATCH 294/303] CLOUDSTACK-2972: due to change on master, using name instead of uuid to find vm name, so break object_store branch --- .../kvm/storage/KVMStorageProcessor.java | 413 ++++++++---------- 1 file changed, 175 insertions(+), 238 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index f0f916a411c..6e71492471a 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -88,39 +88,35 @@ public class KVMStorageProcessor implements StorageProcessor { private String _createTmplPath; private String _manageSnapshotPath; private int _cmdsTimeout; + public KVMStorageProcessor(KVMStoragePoolManager storagePoolMgr, LibvirtComputingResource resource) { this.storagePoolMgr = storagePoolMgr; this.resource = resource; } - + protected String getDefaultStorageScriptsDir() { return "scripts/storage/qcow2"; } - - public boolean configure(String name, Map params) - throws ConfigurationException { + + public boolean configure(String name, Map params) throws ConfigurationException { storageLayer = new JavaStorageLayer(); storageLayer.configure("StorageLayer", params); - + String storageScriptsDir = (String) params.get("storage.scripts.dir"); if (storageScriptsDir == null) { storageScriptsDir = getDefaultStorageScriptsDir(); } - - _createTmplPath = Script - .findScript(storageScriptsDir, "createtmplt.sh"); + + _createTmplPath = Script.findScript(storageScriptsDir, "createtmplt.sh"); if (_createTmplPath == null) { - throw new ConfigurationException( - "Unable to find the createtmplt.sh"); + throw new ConfigurationException("Unable to find the createtmplt.sh"); } - - _manageSnapshotPath = Script.findScript(storageScriptsDir, - "managesnapshot.sh"); + + _manageSnapshotPath = Script.findScript(storageScriptsDir, "managesnapshot.sh"); if (_manageSnapshotPath == null) { - throw new ConfigurationException( - "Unable to find the managesnapshot.sh"); + throw new ConfigurationException("Unable to find the managesnapshot.sh"); } - + String value = (String) params.get("cmds.timeout"); _cmdsTimeout = NumbersUtil.parseInt(value, 7200) * 1000; return true; @@ -128,18 +124,18 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - TemplateObjectTO template = (TemplateObjectTO)srcData; + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + TemplateObjectTO template = (TemplateObjectTO) srcData; DataStoreTO imageStore = template.getDataStore(); - TemplateObjectTO volume = (TemplateObjectTO)destData; - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); - + TemplateObjectTO volume = (TemplateObjectTO) destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore(); + if (!(imageStore instanceof NfsTO)) { return new CopyCmdAnswer("unsupported protocol"); } - - NfsTO nfsImageStore = (NfsTO)imageStore; + + NfsTO nfsImageStore = (NfsTO) imageStore; String tmplturl = nfsImageStore.getUrl() + File.separator + template.getPath(); int index = tmplturl.lastIndexOf("/"); String mountpoint = tmplturl.substring(0, index); @@ -158,9 +154,8 @@ public class KVMStorageProcessor implements StorageProcessor { secondaryPool.refresh(); List disks = secondaryPool.listPhysicalDisks(); if (disks == null || disks.isEmpty()) { - return new PrimaryStorageDownloadAnswer( - "Failed to get volumes from pool: " - + secondaryPool.getUuid()); + return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + + secondaryPool.getUuid()); } for (KVMPhysicalDisk disk : disks) { if (disk.getName().endsWith("qcow2")) { @@ -169,21 +164,19 @@ public class KVMStorageProcessor implements StorageProcessor { } } if (tmplVol == null) { - return new PrimaryStorageDownloadAnswer( - "Failed to get template from pool: " - + secondaryPool.getUuid()); + return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + + secondaryPool.getUuid()); } } else { tmplVol = secondaryPool.getPhysicalDisk(tmpltname); } /* Copy volume to primary storage */ - KVMStoragePool primaryPool = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); - KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk( - tmplVol, UUID.randomUUID().toString(), primaryPool); + KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), + primaryPool); TemplateObjectTO newTemplate = new TemplateObjectTO(); newTemplate.setPath(primaryVol.getName()); @@ -197,7 +190,7 @@ public class KVMStorageProcessor implements StorageProcessor { } } } - + // this is much like PrimaryStorageDownloadCommand, but keeping it separate private KVMPhysicalDisk templateToPrimaryDownload(String templateUrl, KVMStoragePool primaryPool) { int index = templateUrl.lastIndexOf("/"); @@ -235,10 +228,11 @@ public class KVMStorageProcessor implements StorageProcessor { /* Copy volume to primary storage */ - KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), primaryPool); + KVMPhysicalDisk primaryVol = storagePoolMgr.copyPhysicalDisk(templateVol, UUID.randomUUID().toString(), + primaryPool); return primaryVol; } catch (CloudRuntimeException e) { - s_logger.error("Failed to download template to primary storage",e); + s_logger.error("Failed to download template to primary storage", e); return null; } finally { if (secondaryPool != null) { @@ -249,38 +243,35 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - TemplateObjectTO template = (TemplateObjectTO)srcData; + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + TemplateObjectTO template = (TemplateObjectTO) srcData; DataStoreTO imageStore = template.getDataStore(); - VolumeObjectTO volume = (VolumeObjectTO)destData; - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); + VolumeObjectTO volume = (VolumeObjectTO) destData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore(); KVMPhysicalDisk BaseVol = null; KVMStoragePool primaryPool = null; KVMPhysicalDisk vol = null; - + try { - primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), - primaryStore.getUuid()); + primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); String templatePath = template.getPath(); - - if(primaryPool.getType() == StoragePoolType.CLVM) { + + if (primaryPool.getType() == StoragePoolType.CLVM) { vol = templateToPrimaryDownload(templatePath, primaryPool); } else { BaseVol = primaryPool.getPhysicalDisk(templatePath); - vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID - .randomUUID().toString(), primaryPool); + vol = storagePoolMgr.createDiskFromTemplate(BaseVol, UUID.randomUUID().toString(), primaryPool); } if (vol == null) { - return new CopyCmdAnswer( - " Can't create storage volume on storage pool"); + return new CopyCmdAnswer(" Can't create storage volume on storage pool"); } VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(vol.getName()); newVol.setSize(vol.getSize()); - + return new CopyCmdAnswer(newVol); } catch (CloudRuntimeException e) { s_logger.debug("Failed to create volume: " + e.toString()); @@ -301,45 +292,39 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer createTemplateFromVolume(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - TemplateObjectTO template = (TemplateObjectTO)destData; + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); + TemplateObjectTO template = (TemplateObjectTO) destData; DataStoreTO imageStore = template.getDataStore(); - VolumeObjectTO volume = (VolumeObjectTO)srcData; - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); - + VolumeObjectTO volume = (VolumeObjectTO) srcData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore(); + if (!(imageStore instanceof NfsTO)) { return new CopyCmdAnswer("unsupported protocol"); } - NfsTO nfsImageStore = (NfsTO)imageStore; + NfsTO nfsImageStore = (NfsTO) imageStore; KVMStoragePool secondaryStorage = null; KVMStoragePool primary = null; try { String templateFolder = template.getPath(); - secondaryStorage = storagePoolMgr.getStoragePoolByURI( - nfsImageStore.getUrl()); + secondaryStorage = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl()); try { - primary = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), - primaryStore.getUuid()); + primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); } catch (CloudRuntimeException e) { if (e.getMessage().contains("not found")) { - primary = storagePoolMgr.createStoragePool(primaryStore.getUuid(), - primaryStore.getHost(), primaryStore.getPort(), - primaryStore.getPath(), null, - primaryStore.getPoolType()); + primary = storagePoolMgr.createStoragePool(primaryStore.getUuid(), primaryStore.getHost(), + primaryStore.getPort(), primaryStore.getPath(), null, primaryStore.getPoolType()); } else { return new CopyCmdAnswer(e.getMessage()); } } KVMPhysicalDisk disk = primary.getPhysicalDisk(volume.getPath()); - String tmpltPath = secondaryStorage.getLocalPath() + File.separator - + templateFolder; + String tmpltPath = secondaryStorage.getLocalPath() + File.separator + templateFolder; this.storageLayer.mkdirs(tmpltPath); String templateName = UUID.randomUUID().toString(); @@ -359,10 +344,7 @@ public class KVMStorageProcessor implements StorageProcessor { s_logger.debug("Converting RBD disk " + disk.getPath() + " into template " + templateName); QemuImgFile srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primary.getSourceHost(), - primary.getSourcePort(), - primary.getAuthUserName(), - primary.getAuthSecret(), - disk.getPath())); + primary.getSourcePort(), primary.getAuthUserName(), primary.getAuthSecret(), disk.getPath())); srcFile.setFormat(PhysicalDiskFormat.RAW); QemuImgFile destFile = new QemuImgFile(tmpltPath + "/" + templateName + ".qcow2"); @@ -372,8 +354,8 @@ public class KVMStorageProcessor implements StorageProcessor { try { q.convert(srcFile, destFile); } catch (QemuImgException e) { - s_logger.error("Failed to create new template while converting " - + srcFile.getFileName() + " to " + destFile.getFileName() + " the error was: " + e.getMessage()); + s_logger.error("Failed to create new template while converting " + srcFile.getFileName() + " to " + + destFile.getFileName() + " the error was: " + e.getMessage()); } File templateProp = new File(tmpltPath + "/template.properties"); @@ -399,8 +381,7 @@ public class KVMStorageProcessor implements StorageProcessor { qcow2Processor.configure("QCOW2 Processor", params); - FormatInfo info = qcow2Processor.process(tmpltPath, null, - templateName); + FormatInfo info = qcow2Processor.process(tmpltPath, null, templateName); TemplateLocation loc = new TemplateLocation(this.storageLayer, tmpltPath); loc.create(1, true, templateName); @@ -413,8 +394,8 @@ public class KVMStorageProcessor implements StorageProcessor { newTemplate.setFormat(ImageFormat.QCOW2); return new CopyCmdAnswer(newTemplate); } catch (Exception e) { - s_logger.debug("Failed to create template from volume: " + e.toString()); - return new CopyCmdAnswer(e.toString()); + s_logger.debug("Failed to create template from volume: " + e.toString()); + return new CopyCmdAnswer(e.toString()); } finally { if (secondaryStorage != null) { secondaryStorage.delete(); @@ -424,23 +405,23 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer backupSnasphot(CopyCommand cmd) { - DataTO srcData = cmd.getSrcTO(); - DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); - SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshot.getDataStore(); - SnapshotObjectTO destSnapshot = (SnapshotObjectTO)destData; + DataTO srcData = cmd.getSrcTO(); + DataTO destData = cmd.getDestTO(); + int wait = cmd.getWait(); + SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData; + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshot.getDataStore(); + SnapshotObjectTO destSnapshot = (SnapshotObjectTO) destData; DataStoreTO imageStore = destData.getDataStore(); - + if (!(imageStore instanceof NfsTO)) { return new CopyCmdAnswer("unsupported protocol"); } - NfsTO nfsImageStore = (NfsTO)imageStore; - + NfsTO nfsImageStore = (NfsTO) imageStore; + String secondaryStoragePoolUrl = nfsImageStore.getUrl(); - //NOTE: snapshot name is encoded in snapshot path + // NOTE: snapshot name is encoded in snapshot path int index = snapshot.getPath().lastIndexOf("/"); - + String snapshotName = snapshot.getPath().substring(index + 1); String volumePath = snapshot.getVolume().getPath(); String snapshotDestPath = null; @@ -450,19 +431,16 @@ public class KVMStorageProcessor implements StorageProcessor { try { Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - secondaryStoragePool = storagePoolMgr.getStoragePoolByURI( - secondaryStoragePoolUrl); + secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl); String ssPmountPath = secondaryStoragePool.getLocalPath(); snapshotRelPath = destSnapshot.getPath(); snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath; - KVMStoragePool primaryPool = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(volumePath); - Script command = new Script(_manageSnapshotPath, _cmdsTimeout, - s_logger); + Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); command.add("-b", snapshotDisk.getPath()); command.add("-n", snapshotName); command.add("-p", snapshotDestPath); @@ -485,11 +463,9 @@ public class KVMStorageProcessor implements StorageProcessor { } } - KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), + KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); - if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING - && !primaryStorage.isExternalSnapshot()) { + if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) { DomainSnapshot snap = vm.snapshotLookupByName(snapshotName); snap.delete(0); @@ -503,21 +479,18 @@ public class KVMStorageProcessor implements StorageProcessor { vm.resume(); } } else { - command = new Script(_manageSnapshotPath, _cmdsTimeout, - s_logger); + command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); command.add("-d", snapshotDisk.getPath()); command.add("-n", snapshotName); result = command.execute(); if (result != null) { s_logger.debug("Failed to backup snapshot: " + result); - return new CopyCmdAnswer( - "Failed to backup snapshot: " + result); + return new CopyCmdAnswer("Failed to backup snapshot: " + result); } } - + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - newSnapshot.setPath(snapshotRelPath - + File.separator + snapshotName); + newSnapshot.setPath(snapshotRelPath + File.separator + snapshotName); return new CopyCmdAnswer(newSnapshot); } catch (LibvirtException e) { s_logger.debug("Failed to backup snapshot: " + e.toString()); @@ -532,16 +505,14 @@ public class KVMStorageProcessor implements StorageProcessor { } } - protected synchronized String attachOrDetachISO(Connect conn, - String vmName, String isoPath, boolean isAttach) - throws LibvirtException, URISyntaxException, InternalErrorException { + protected synchronized String attachOrDetachISO(Connect conn, String vmName, String isoPath, boolean isAttach) + throws LibvirtException, URISyntaxException, InternalErrorException { String isoXml = null; if (isoPath != null && isAttach) { int index = isoPath.lastIndexOf("/"); String path = isoPath.substring(0, index); String name = isoPath.substring(index + 1); - KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI( - path); + KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(path); KVMPhysicalDisk isoVol = secondaryPool.getPhysicalDisk(name); isoPath = isoVol.getPath(); @@ -566,19 +537,19 @@ public class KVMStorageProcessor implements StorageProcessor { } return result; } + @Override public Answer attachIso(AttachCommand cmd) { DiskTO disk = cmd.getDisk(); - TemplateObjectTO isoTO = (TemplateObjectTO)disk.getData(); + TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData(); DataStoreTO store = isoTO.getDataStore(); if (!(store instanceof NfsTO)) { - return new AttachAnswer("unsupported protocol"); + return new AttachAnswer("unsupported protocol"); } - NfsTO nfsStore = (NfsTO)store; + NfsTO nfsStore = (NfsTO) store; try { Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); - attachOrDetachISO(conn, cmd.getVmName(), nfsStore.getUrl() + File.separator + isoTO.getPath(), - true); + attachOrDetachISO(conn, cmd.getVmName(), nfsStore.getUrl() + File.separator + isoTO.getPath(), true); } catch (LibvirtException e) { return new Answer(cmd, false, e.toString()); } catch (URISyntaxException e) { @@ -589,14 +560,12 @@ public class KVMStorageProcessor implements StorageProcessor { return new Answer(cmd); } - - protected synchronized String attachOrDetachDevice(Connect conn, - boolean attach, String vmName, String xml) throws LibvirtException, - InternalErrorException { + + protected synchronized String attachOrDetachDevice(Connect conn, boolean attach, String vmName, String xml) + throws LibvirtException, InternalErrorException { Domain dm = null; try { - dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes((vmName - .getBytes()))); + dm = conn.domainLookupByName(vmName); if (attach) { s_logger.debug("Attaching device: " + xml); @@ -607,11 +576,9 @@ public class KVMStorageProcessor implements StorageProcessor { } } catch (LibvirtException e) { if (attach) { - s_logger.warn("Failed to attach device to " + vmName + ": " - + e.getMessage()); + s_logger.warn("Failed to attach device to " + vmName + ": " + e.getMessage()); } else { - s_logger.warn("Failed to detach device from " + vmName + ": " - + e.getMessage()); + s_logger.warn("Failed to detach device from " + vmName + ": " + e.getMessage()); } throw e; } finally { @@ -626,17 +593,15 @@ public class KVMStorageProcessor implements StorageProcessor { return null; } - - protected synchronized String attachOrDetachDisk(Connect conn, - boolean attach, String vmName, KVMPhysicalDisk attachingDisk, - int devId) throws LibvirtException, InternalErrorException { + + protected synchronized String attachOrDetachDisk(Connect conn, boolean attach, String vmName, + KVMPhysicalDisk attachingDisk, int devId) throws LibvirtException, InternalErrorException { List disks = null; Domain dm = null; DiskDef diskdef = null; try { if (!attach) { - dm = conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName - .getBytes())); + dm = conn.domainLookupByName(vmName); LibvirtDomainXMLParser parser = new LibvirtDomainXMLParser(); String xml = dm.getXMLDesc(0); parser.parseDomainXML(xml); @@ -644,25 +609,21 @@ public class KVMStorageProcessor implements StorageProcessor { for (DiskDef disk : disks) { String file = disk.getDiskPath(); - if (file != null - && file.equalsIgnoreCase(attachingDisk.getPath())) { + if (file != null && file.equalsIgnoreCase(attachingDisk.getPath())) { diskdef = disk; break; } } if (diskdef == null) { - throw new InternalErrorException("disk: " - + attachingDisk.getPath() - + " is not attached before"); + throw new InternalErrorException("disk: " + attachingDisk.getPath() + " is not attached before"); } } else { diskdef = new DiskDef(); if (attachingDisk.getFormat() == PhysicalDiskFormat.QCOW2) { - diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, - DiskDef.diskBus.VIRTIO, DiskDef.diskFmtType.QCOW2); + diskdef.defFileBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO, + DiskDef.diskFmtType.QCOW2); } else if (attachingDisk.getFormat() == PhysicalDiskFormat.RAW) { - diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, - DiskDef.diskBus.VIRTIO); + diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, DiskDef.diskBus.VIRTIO); } } @@ -677,20 +638,17 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer attachVolume(AttachCommand cmd) { - DiskTO disk = cmd.getDisk(); - VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); + DiskTO disk = cmd.getDisk(); + VolumeObjectTO vol = (VolumeObjectTO) disk.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) vol.getDataStore(); String vmName = cmd.getVmName(); try { Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - KVMStoragePool primary = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), - primaryStore.getUuid()); - + KVMStoragePool primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); + KVMPhysicalDisk phyDisk = primary.getPhysicalDisk(vol.getPath()); - attachOrDetachDisk(conn, true, vmName, phyDisk, - disk.getDiskSeq().intValue()); - + attachOrDetachDisk(conn, true, vmName, phyDisk, disk.getDiskSeq().intValue()); + return new AttachAnswer(disk); } catch (LibvirtException e) { s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); @@ -709,20 +667,17 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer dettachVolume(DettachCommand cmd) { - DiskTO disk = cmd.getDisk(); - VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); + DiskTO disk = cmd.getDisk(); + VolumeObjectTO vol = (VolumeObjectTO) disk.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) vol.getDataStore(); String vmName = cmd.getVmName(); try { Connect conn = LibvirtConnection.getConnectionByVmName(vmName); - KVMStoragePool primary = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), - primaryStore.getUuid()); - + KVMStoragePool primary = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); + KVMPhysicalDisk phyDisk = primary.getPhysicalDisk(vol.getPath()); - attachOrDetachDisk(conn, false, vmName, phyDisk, - disk.getDiskSeq().intValue()); - + attachOrDetachDisk(conn, false, vmName, phyDisk, disk.getDiskSeq().intValue()); + return new DettachAnswer(disk); } catch (LibvirtException e) { s_logger.debug("Failed to attach volume: " + vol.getPath() + ", due to " + e.toString()); @@ -735,39 +690,35 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer createVolume(CreateObjectCommand cmd) { - VolumeObjectTO volume = (VolumeObjectTO)cmd.getData(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volume.getDataStore(); - + VolumeObjectTO volume = (VolumeObjectTO) cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) volume.getDataStore(); + KVMStoragePool primaryPool = null; KVMPhysicalDisk vol = null; long disksize; try { - primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), - primaryStore.getUuid()); + primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); disksize = volume.getSize(); - vol = primaryPool.createPhysicalDisk(UUID.randomUUID() - .toString(), disksize); + vol = primaryPool.createPhysicalDisk(UUID.randomUUID().toString(), disksize); VolumeObjectTO newVol = new VolumeObjectTO(); newVol.setPath(vol.getName()); - + return new CreateObjectAnswer(newVol); } catch (Exception e) { s_logger.debug("Failed to create volume: " + e.toString()); return new CreateObjectAnswer(e.toString()); } } - - protected static MessageFormat SnapshotXML = new MessageFormat( - " " + " {0}" + " " - + " {1}" + " " - + " "); + + protected static MessageFormat SnapshotXML = new MessageFormat(" " + " {0}" + + " " + " {1}" + " " + " "); @Override public Answer createSnapshot(CreateObjectCommand cmd) { - SnapshotObjectTO snapshotTO = (SnapshotObjectTO)cmd.getData(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)snapshotTO.getDataStore(); + SnapshotObjectTO snapshotTO = (SnapshotObjectTO) cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshotTO.getDataStore(); VolumeObjectTO volume = snapshotTO.getVolume(); String snapshotName = UUID.randomUUID().toString(); String vmName = volume.getVmName(); @@ -784,24 +735,21 @@ public class KVMStorageProcessor implements StorageProcessor { } } - KVMStoragePool primaryPool = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); if (primaryPool.getType() == StoragePoolType.RBD) { s_logger.debug("Snapshots are not supported on RBD volumes"); - return new CreateObjectAnswer( - "Snapshots are not supported on RBD volumes"); + return new CreateObjectAnswer("Snapshots are not supported on RBD volumes"); } KVMPhysicalDisk disk = primaryPool.getPhysicalDisk(volume.getPath()); - if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING - && !primaryPool.isExternalSnapshot()) { + if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryPool.isExternalSnapshot()) { String vmUuid = vm.getUUIDString(); Object[] args = new Object[] { snapshotName, vmUuid }; String snapshot = SnapshotXML.format(args); s_logger.debug(snapshot); - + vm.snapshotCreateXML(snapshot); /* * libvirt on RHEL6 doesn't handle resume event emitted from @@ -815,40 +763,35 @@ public class KVMStorageProcessor implements StorageProcessor { } else { /* VM is not running, create a snapshot by ourself */ - final Script command = new Script(_manageSnapshotPath, - this._cmdsTimeout, s_logger); + final Script command = new Script(_manageSnapshotPath, this._cmdsTimeout, s_logger); command.add("-c", disk.getPath()); command.add("-n", snapshotName); String result = command.execute(); if (result != null) { s_logger.debug("Failed to manage snapshot: " + result); - return new CreateObjectAnswer( - "Failed to manage snapshot: " + result); + return new CreateObjectAnswer("Failed to manage snapshot: " + result); } } - + SnapshotObjectTO newSnapshot = new SnapshotObjectTO(); - //NOTE: sort of hack, we'd better just put snapshtoName + // NOTE: sort of hack, we'd better just put snapshtoName newSnapshot.setPath(disk.getPath() + File.separator + snapshotName); return new CreateObjectAnswer(newSnapshot); } catch (LibvirtException e) { s_logger.debug("Failed to manage snapshot: " + e.toString()); - return new CreateObjectAnswer( - "Failed to manage snapshot: " + e.toString()); + return new CreateObjectAnswer("Failed to manage snapshot: " + e.toString()); } } @Override public Answer deleteVolume(DeleteCommand cmd) { - VolumeObjectTO vol = (VolumeObjectTO)cmd.getData(); - PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)vol.getDataStore(); + VolumeObjectTO vol = (VolumeObjectTO) cmd.getData(); + PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) vol.getDataStore(); try { - KVMStoragePool pool = storagePoolMgr.getStoragePool( - primaryStore.getPoolType(), - primaryStore.getUuid()); + KVMStoragePool pool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); try { pool.getPhysicalDisk(vol.getPath()); - } catch(Exception e) { + } catch (Exception e) { s_logger.debug("can't find volume: " + vol.getPath() + ", return true"); return new Answer(null); } @@ -862,48 +805,42 @@ public class KVMStorageProcessor implements StorageProcessor { @Override public Answer createVolumeFromSnapshot(CopyCommand cmd) { - try { - DataTO srcData = cmd.getSrcTO(); - SnapshotObjectTO snapshot = (SnapshotObjectTO)srcData; - DataTO destData = cmd.getDestTO(); - PrimaryDataStoreTO pool = (PrimaryDataStoreTO)destData.getDataStore(); - DataStoreTO imageStore = srcData.getDataStore(); + try { + DataTO srcData = cmd.getSrcTO(); + SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData; + DataTO destData = cmd.getDestTO(); + PrimaryDataStoreTO pool = (PrimaryDataStoreTO) destData.getDataStore(); + DataStoreTO imageStore = srcData.getDataStore(); + if (!(imageStore instanceof NfsTO)) { + return new CopyCmdAnswer("unsupported protocol"); + } - if (!(imageStore instanceof NfsTO)) { - return new CopyCmdAnswer("unsupported protocol"); - } + NfsTO nfsImageStore = (NfsTO) imageStore; - NfsTO nfsImageStore = (NfsTO)imageStore; + String snapshotPath = snapshot.getPath(); + int index = snapshotPath.lastIndexOf("/"); + snapshotPath = snapshotPath.substring(0, index); + String snapshotName = snapshotPath.substring(index + 1); + KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI(nfsImageStore.getUrl() + File.separator + + snapshotPath); + KVMPhysicalDisk snapshotDisk = secondaryPool.getPhysicalDisk(snapshotName); - String snapshotPath = snapshot.getPath(); - int index = snapshotPath.lastIndexOf("/"); - snapshotPath = snapshotPath.substring(0, index); - String snapshotName = snapshotPath.substring(index + 1); - KVMStoragePool secondaryPool = storagePoolMgr.getStoragePoolByURI( - nfsImageStore.getUrl() + File.separator + snapshotPath); - KVMPhysicalDisk snapshotDisk = secondaryPool.getPhysicalDisk(snapshotName); - - String primaryUuid = pool.getUuid(); - KVMStoragePool primaryPool = storagePoolMgr - .getStoragePool(pool.getPoolType(), - primaryUuid); - String volUuid = UUID.randomUUID().toString(); - KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, - volUuid, primaryPool); - VolumeObjectTO newVol = new VolumeObjectTO(); - newVol.setPath(disk.getName()); - newVol.setSize(disk.getVirtualSize()); - return new CopyCmdAnswer( - newVol); - } catch (CloudRuntimeException e) { - return new CopyCmdAnswer(e.toString() - ); - } + String primaryUuid = pool.getUuid(); + KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(pool.getPoolType(), primaryUuid); + String volUuid = UUID.randomUUID().toString(); + KVMPhysicalDisk disk = storagePoolMgr.copyPhysicalDisk(snapshotDisk, volUuid, primaryPool); + VolumeObjectTO newVol = new VolumeObjectTO(); + newVol.setPath(disk.getName()); + newVol.setSize(disk.getVirtualSize()); + return new CopyCmdAnswer(newVol); + } catch (CloudRuntimeException e) { + return new CopyCmdAnswer(e.toString()); + } } - @Override - public Answer deleteSnapshot(DeleteCommand cmd) { - return new Answer(cmd); - } + @Override + public Answer deleteSnapshot(DeleteCommand cmd) { + return new Answer(cmd); + } } From 34f65384548b9960020660614df0b15d7379b682 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 14 Jun 2013 17:57:34 -0700 Subject: [PATCH 295/303] CLOUDSTACK-2970: wait is in seconds in command --- .../kvm/resource/LibvirtConnection.java | 23 ++++++++----------- .../kvm/storage/KVMStorageProcessor.java | 5 ++-- scripts/storage/qcow2/createtmplt.sh | 4 ++-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java index 2fc54253f57..ea8429e9362 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtConnection.java @@ -16,19 +16,18 @@ // under the License. package com.cloud.hypervisor.kvm.resource; -import com.cloud.hypervisor.Hypervisor; -import com.cloud.hypervisor.Hypervisor.HypervisorType; +import java.util.HashMap; +import java.util.Map; + import org.apache.log4j.Logger; import org.libvirt.Connect; import org.libvirt.LibvirtException; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; +import com.cloud.hypervisor.Hypervisor; +import com.cloud.hypervisor.Hypervisor.HypervisorType; public class LibvirtConnection { - private static final Logger s_logger = Logger - .getLogger(LibvirtConnection.class); + private static final Logger s_logger = Logger.getLogger(LibvirtConnection.class); static private Map _connections = new HashMap(); static private Connect _connection; @@ -48,8 +47,7 @@ public class LibvirtConnection { try { conn.getVersion(); } catch (LibvirtException e) { - s_logger.debug("Connection with libvirtd is broken, due to " - + e.getMessage()); + s_logger.debug("Connection with libvirtd is broken, due to " + e.getMessage()); conn = new Connect(hypervisorURI, false); _connections.put(hypervisorURI, conn); } @@ -59,17 +57,16 @@ public class LibvirtConnection { } static public Connect getConnectionByVmName(String vmName) throws LibvirtException { - HypervisorType[] hypervisors = new HypervisorType[] {HypervisorType.KVM, Hypervisor.HypervisorType.LXC}; + HypervisorType[] hypervisors = new HypervisorType[] { HypervisorType.KVM, Hypervisor.HypervisorType.LXC }; - for (HypervisorType hypervisor : hypervisors) { try { Connect conn = LibvirtConnection.getConnectionByType(hypervisor.toString()); - if (conn.domainLookupByUUID(UUID.nameUUIDFromBytes(vmName.getBytes())) != null) { + if (conn.domainLookupByName(vmName) != null) { return conn; } } catch (Exception e) { - s_logger.debug("can't find connection: " + hypervisor.toString() + ", for vm: " + vmName + ", continue"); + s_logger.debug("can't find connection: " + hypervisor.toString() + ", for vm: " + vmName + ", continue"); } } diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 6e71492471a..62208a5d091 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -329,7 +329,7 @@ public class KVMStorageProcessor implements StorageProcessor { String templateName = UUID.randomUUID().toString(); if (primary.getType() != StoragePoolType.RBD) { - Script command = new Script(_createTmplPath, wait, s_logger); + Script command = new Script(_createTmplPath, wait * 1000, s_logger); command.add("-f", disk.getPath()); command.add("-t", tmpltPath); command.add("-n", templateName + ".qcow2"); @@ -407,7 +407,6 @@ public class KVMStorageProcessor implements StorageProcessor { public Answer backupSnasphot(CopyCommand cmd) { DataTO srcData = cmd.getSrcTO(); DataTO destData = cmd.getDestTO(); - int wait = cmd.getWait(); SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData; PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshot.getDataStore(); SnapshotObjectTO destSnapshot = (SnapshotObjectTO) destData; @@ -440,7 +439,7 @@ public class KVMStorageProcessor implements StorageProcessor { KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid()); KVMPhysicalDisk snapshotDisk = primaryPool.getPhysicalDisk(volumePath); - Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger); + Script command = new Script(_manageSnapshotPath, cmd.getWait() * 1000, s_logger); command.add("-b", snapshotDisk.getPath()); command.add("-n", snapshotName); command.add("-p", snapshotDestPath); diff --git a/scripts/storage/qcow2/createtmplt.sh b/scripts/storage/qcow2/createtmplt.sh index 152268f651a..8d6dd0d4849 100755 --- a/scripts/storage/qcow2/createtmplt.sh +++ b/scripts/storage/qcow2/createtmplt.sh @@ -27,10 +27,10 @@ usage() { #set -x qemu_img="cloud-qemu-img" -which $qemu_img +which $qemu_img >& /dev/null if [ $? -gt 0 ] then - which qemu-img + which qemu-img >& /dev/null if [ $? -eq 0 ] then qemu_img="qemu-img" From c4267b546f2bde8c0b32f13eea984896625ed269 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 14 Jun 2013 18:15:20 -0700 Subject: [PATCH 296/303] CLOUDSTACK-2973: fix detach iso --- .../kvm/storage/KVMStorageProcessor.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java index 62208a5d091..8dce094f358 100644 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java @@ -560,6 +560,29 @@ public class KVMStorageProcessor implements StorageProcessor { return new Answer(cmd); } + @Override + public Answer dettachIso(DettachCommand cmd) { + DiskTO disk = cmd.getDisk(); + TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData(); + DataStoreTO store = isoTO.getDataStore(); + if (!(store instanceof NfsTO)) { + return new AttachAnswer("unsupported protocol"); + } + NfsTO nfsStore = (NfsTO) store; + try { + Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName()); + attachOrDetachISO(conn, cmd.getVmName(), nfsStore.getUrl() + File.separator + isoTO.getPath(), false); + } catch (LibvirtException e) { + return new Answer(cmd, false, e.toString()); + } catch (URISyntaxException e) { + return new Answer(cmd, false, e.toString()); + } catch (InternalErrorException e) { + return new Answer(cmd, false, e.toString()); + } + + return new Answer(cmd); + } + protected synchronized String attachOrDetachDevice(Connect conn, boolean attach, String vmName, String xml) throws LibvirtException, InternalErrorException { Domain dm = null; @@ -658,12 +681,6 @@ public class KVMStorageProcessor implements StorageProcessor { } } - @Override - public Answer dettachIso(DettachCommand cmd) { - // TODO Auto-generated method stub - return null; - } - @Override public Answer dettachVolume(DettachCommand cmd) { DiskTO disk = cmd.getDisk(); From e8b0cff1c607888ea9299f3aa92dd7c27c5692e5 Mon Sep 17 00:00:00 2001 From: Edison Su Date: Fri, 14 Jun 2013 18:26:20 -0700 Subject: [PATCH 297/303] CLOUDSTACK-2658: timeout can't be null --- ...VmwareSecondaryStorageResourceHandler.java | 135 ++++---- .../resource/NfsSecondaryStorageResource.java | 323 ++++++++++-------- 2 files changed, 252 insertions(+), 206 deletions(-) diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java index 4d04ffe40a4..22ba59f36ca 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java @@ -18,13 +18,9 @@ package com.cloud.storage.resource; import java.util.List; -import org.apache.log4j.Logger; - -import com.google.gson.Gson; -import com.vmware.vim25.ManagedObjectReference; - import org.apache.cloudstack.storage.command.StorageSubSystemCommand; import org.apache.cloudstack.storage.resource.SecondaryStorageResourceHandler; +import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.BackupSnapshotCommand; @@ -50,8 +46,11 @@ import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.serializer.GsonHelper; import com.cloud.utils.Pair; +import com.google.gson.Gson; +import com.vmware.vim25.ManagedObjectReference; -public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageResourceHandler, VmwareHostService, VmwareStorageMount { +public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageResourceHandler, VmwareHostService, + VmwareStorageMount { private static final Logger s_logger = Logger.getLogger(VmwareSecondaryStorageResourceHandler.class); private final PremiumSecondaryStorageResource _resource; @@ -61,17 +60,16 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe private final StorageSubsystemCommandHandler storageSubsystemHandler; /* - private Map _activeHosts = new HashMap(); + * private Map _activeHosts = new HashMap(); */ public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource) { _resource = resource; _storageMgr = new VmwareStorageManagerImpl(this); _gson = GsonHelper.getGsonLogger(); - - VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, - null, null, null - ); + + VmwareStorageProcessor storageProcessor = new VmwareStorageProcessor(this, true, this, resource.getTimeout(), + null, null); storageSubsystemHandler = new StorageSubsystemCommandHandlerBase(storageProcessor); } @@ -79,37 +77,37 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe public Answer executeRequest(Command cmd) { Answer answer; if (cmd instanceof PrimaryStorageDownloadCommand) { - answer = execute((PrimaryStorageDownloadCommand)cmd); - } else if(cmd instanceof BackupSnapshotCommand) { - answer = execute((BackupSnapshotCommand)cmd); - } else if(cmd instanceof CreatePrivateTemplateFromVolumeCommand) { - answer = execute((CreatePrivateTemplateFromVolumeCommand)cmd); - } else if(cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { - answer = execute((CreatePrivateTemplateFromSnapshotCommand)cmd); - } else if(cmd instanceof CopyVolumeCommand) { - answer = execute((CopyVolumeCommand)cmd); - } else if(cmd instanceof CreateVolumeOVACommand) { - answer = execute((CreateVolumeOVACommand)cmd); + answer = execute((PrimaryStorageDownloadCommand) cmd); + } else if (cmd instanceof BackupSnapshotCommand) { + answer = execute((BackupSnapshotCommand) cmd); + } else if (cmd instanceof CreatePrivateTemplateFromVolumeCommand) { + answer = execute((CreatePrivateTemplateFromVolumeCommand) cmd); + } else if (cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { + answer = execute((CreatePrivateTemplateFromSnapshotCommand) cmd); + } else if (cmd instanceof CopyVolumeCommand) { + answer = execute((CopyVolumeCommand) cmd); + } else if (cmd instanceof CreateVolumeOVACommand) { + answer = execute((CreateVolumeOVACommand) cmd); } else if (cmd instanceof PrepareOVAPackingCommand) { - answer = execute((PrepareOVAPackingCommand)cmd); - } else if(cmd instanceof CreateVolumeFromSnapshotCommand) { - answer = execute((CreateVolumeFromSnapshotCommand)cmd); + answer = execute((PrepareOVAPackingCommand) cmd); + } else if (cmd instanceof CreateVolumeFromSnapshotCommand) { + answer = execute((CreateVolumeFromSnapshotCommand) cmd); } else if (cmd instanceof StorageSubSystemCommand) { - answer = storageSubsystemHandler.handleStorageCommands((StorageSubSystemCommand)cmd); + answer = storageSubsystemHandler.handleStorageCommands((StorageSubSystemCommand) cmd); } else { - answer = _resource.defaultAction(cmd); + answer = _resource.defaultAction(cmd); } // special handling to pass-back context info for cleanups - if(cmd.getContextParam("execid") != null) { + if (cmd.getContextParam("execid") != null) { answer.setContextParam("execid", cmd.getContextParam("execid")); } - if(cmd.getContextParam("checkpoint") != null) { + if (cmd.getContextParam("checkpoint") != null) { answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint")); } - if(cmd.getContextParam("checkpoint2") != null) { + if (cmd.getContextParam("checkpoint2") != null) { answer.setContextParam("checkpoint2", cmd.getContextParam("checkpoint2")); } @@ -184,13 +182,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe @Override public VmwareContext getServiceContext(Command cmd) { String guid = cmd.getContextParam("guid"); - if(guid == null || guid.isEmpty()) { + if (guid == null || guid.isEmpty()) { s_logger.error("Invalid command context parameter guid"); return null; } String username = cmd.getContextParam("username"); - if(username == null || username.isEmpty()) { + if (username == null || username.isEmpty()) { s_logger.error("Invalid command context parameter username"); return null; } @@ -199,14 +197,14 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe // validate command guid parameter String[] tokens = guid.split("@"); - if(tokens == null || tokens.length != 2) { + if (tokens == null || tokens.length != 2) { s_logger.error("Invalid content in command context parameter guid"); return null; } String vCenterAddress = tokens[1]; String[] hostTokens = tokens[0].split(":"); - if(hostTokens == null || hostTokens.length != 2) { + if (hostTokens == null || hostTokens.length != 2) { s_logger.error("Invalid content in command context parameter guid"); return null; } @@ -215,20 +213,21 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe _resource.ensureOutgoingRuleForAddress(vCenterAddress); VmwareContext context = null; - // cached VmwareContext may be timed out in vCenter, give it a chance to reclaim a new context from factory - for(int i = 0; i < 2; i++) { + // cached VmwareContext may be timed out in vCenter, give it a + // chance to reclaim a new context from factory + for (int i = 0; i < 2; i++) { context = VmwareSecondaryStorageContextFactory.create(vCenterAddress, username, password); - if(!validateContext(context, cmd)) { + if (!validateContext(context, cmd)) { invalidateServiceContext(context); } } - if(context != null) { + if (context != null) { context.registerStockObject("serviceconsole", cmd.getContextParam("serviceconsole")); context.registerStockObject("manageportgroup", cmd.getContextParam("manageportgroup")); } return context; - } catch(Exception e) { + } catch (Exception e) { s_logger.error("Unexpected exception " + e.toString(), e); return null; } @@ -242,14 +241,14 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe @Override public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { String guid = cmd.getContextParam("guid"); - assert(guid != null); + assert (guid != null); String[] tokens = guid.split("@"); - assert(tokens != null && tokens.length == 2); + assert (tokens != null && tokens.length == 2); ManagedObjectReference morHyperHost = new ManagedObjectReference(); String[] hostTokens = tokens[0].split(":"); - if(hostTokens == null || hostTokens.length != 2) { + if (hostTokens == null || hostTokens.length != 2) { s_logger.error("Invalid content in command context parameter guid"); return null; } @@ -257,40 +256,42 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe morHyperHost.setType(hostTokens[0]); morHyperHost.setValue(hostTokens[1]); - if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { - HostMO hostMo = new HostMO(context, morHyperHost); + if (morHyperHost.getType().equalsIgnoreCase("HostSystem")) { + HostMO hostMo = new HostMO(context, morHyperHost); try { ManagedObjectReference mor = hostMo.getHyperHostCluster(); ClusterMO clusterMo = new ClusterMO(hostMo.getContext(), mor); List> hostsInCluster = clusterMo.getClusterHosts(); - for(Pair hostPair : hostsInCluster) { + for (Pair hostPair : hostsInCluster) { HostMO hostIteratorMo = new HostMO(hostMo.getContext(), hostPair.first()); - VmwareHypervisorHostNetworkSummary netSummary = hostIteratorMo.getHyperHostNetworkSummary( - hostIteratorMo.getHostType() == VmwareHostType.ESXi ? cmd.getContextParam("manageportgroup") : cmd.getContextParam("serviceconsole")); + VmwareHypervisorHostNetworkSummary netSummary = hostIteratorMo + .getHyperHostNetworkSummary(hostIteratorMo.getHostType() == VmwareHostType.ESXi ? cmd + .getContextParam("manageportgroup") : cmd.getContextParam("serviceconsole")); _resource.ensureOutgoingRuleForAddress(netSummary.getHostIp()); s_logger.info("Setup firewall rule for host: " + netSummary.getHostIp()); } - } catch(Throwable e) { - s_logger.warn("Unable to retrive host network information due to exception " + e.toString() + ", host: " + hostTokens[0] + "-" + hostTokens[1]); + } catch (Throwable e) { + s_logger.warn("Unable to retrive host network information due to exception " + e.toString() + + ", host: " + hostTokens[0] + "-" + hostTokens[1]); } return hostMo; } - assert(false); + assert (false); return new ClusterMO(context, morHyperHost); } @Override public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) { - assert(cmd.getContextParam("worker") != null); - assert(workerSequence < 2); + assert (cmd.getContextParam("worker") != null); + assert (workerSequence < 2); - if(workerSequence == 0) + if (workerSequence == 0) return cmd.getContextParam("worker"); return cmd.getContextParam("worker2"); } @@ -302,40 +303,42 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe private boolean validateContext(VmwareContext context, Command cmd) { String guid = cmd.getContextParam("guid"); - assert(guid != null); + assert (guid != null); String[] tokens = guid.split("@"); - assert(tokens != null && tokens.length == 2); + assert (tokens != null && tokens.length == 2); ManagedObjectReference morHyperHost = new ManagedObjectReference(); String[] hostTokens = tokens[0].split(":"); - assert(hostTokens.length == 2); + assert (hostTokens.length == 2); morHyperHost.setType(hostTokens[0]); morHyperHost.setValue(hostTokens[1]); - if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { - HostMO hostMo = new HostMO(context, morHyperHost); + if (morHyperHost.getType().equalsIgnoreCase("HostSystem")) { + HostMO hostMo = new HostMO(context, morHyperHost); try { - VmwareHypervisorHostNetworkSummary netSummary = hostMo.getHyperHostNetworkSummary( - hostMo.getHostType() == VmwareHostType.ESXi ? cmd.getContextParam("manageportgroup") : cmd.getContextParam("serviceconsole")); - assert(netSummary != null); - if(netSummary.getHostIp() != null && !netSummary.getHostIp().isEmpty()) { - if(s_logger.isDebugEnabled()) { - s_logger.debug("Context validation succeeded. Validated via host: " + netSummary.getHostIp() + ", guid: " + guid); + VmwareHypervisorHostNetworkSummary netSummary = hostMo + .getHyperHostNetworkSummary(hostMo.getHostType() == VmwareHostType.ESXi ? cmd + .getContextParam("manageportgroup") : cmd.getContextParam("serviceconsole")); + assert (netSummary != null); + if (netSummary.getHostIp() != null && !netSummary.getHostIp().isEmpty()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Context validation succeeded. Validated via host: " + netSummary.getHostIp() + + ", guid: " + guid); } return true; } s_logger.warn("Context validation failed due to invalid host network summary"); return false; - } catch(Throwable e) { + } catch (Throwable e) { s_logger.warn("Context validation failed due to " + VmwareHelper.getExceptionMessage(e)); return false; } } - assert(false); + assert (false); return true; } } diff --git a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java index be352db432f..17ec0bbf838 100755 --- a/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java +++ b/services/secondary-storage/src/org/apache/cloudstack/storage/resource/NfsSecondaryStorageResource.java @@ -129,6 +129,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S int _timeout; + public int getTimeout() { + return _timeout; + } + + public void setTimeout(int _timeout) { + this._timeout = _timeout; + } + String _instance; String _dc; String _pod; @@ -229,12 +237,13 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.debug("Directory " + downloadPath + " already exists"); } - File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, new FileNamingStrategy() { - @Override - public String determineFileName(final String key) { - return substringAfterLast(key, S3Utils.SEPARATOR); - } - }); + File destFile = S3Utils.getFile(s3, s3.getBucketName(), srcData.getPath(), downloadDirectory, + new FileNamingStrategy() { + @Override + public String determineFileName(final String key) { + return substringAfterLast(key, S3Utils.SEPARATOR); + } + }); if (destFile == null) { return new CopyCmdAnswer("Can't find template"); @@ -310,9 +319,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - - protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, - TemplateObjectTO destData, NfsTO destDataStore) { + protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, + NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { String srcMountPoint = this.getRootDir(srcDataStore.getUrl()); String snapshotPath = srcData.getPath(); int index = snapshotPath.lastIndexOf("/"); @@ -373,8 +381,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return new CopyCmdAnswer(errMsg); } - protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, - NfsTO destDataStore) { + protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, + TemplateObjectTO destData, NfsTO destDataStore) { if (srcData.getHypervisorType() == HypervisorType.XenServer) { return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore); @@ -395,8 +403,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (destDataStore instanceof NfsTO) { - return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore, (TemplateObjectTO) destData, - (NfsTO) destDataStore); + return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO) srcData, (NfsTO) srcDataStore, + (TemplateObjectTO) destData, (NfsTO) destDataStore); } } @@ -424,7 +432,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return createTemplateFromSnapshot(cmd); } - if (srcDataStore instanceof S3TO && destDataStore instanceof NfsTO && destDataStore.getRole() == DataStoreRole.ImageCache) { + if (srcDataStore instanceof S3TO && destDataStore instanceof NfsTO + && destDataStore.getRole() == DataStoreRole.ImageCache) { S3TO s3 = (S3TO) srcDataStore; NfsTO destImageStore = (NfsTO) destDataStore; return this.copyFromS3ToNfs(cmd, srcData, s3, destData, destImageStore); @@ -438,13 +447,15 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } @SuppressWarnings("unchecked") - protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, final String templateUniqueName) { + protected String determineS3TemplateDirectory(final Long accountId, final Long templateId, + final String templateUniqueName) { return join(asList(TEMPLATE_ROOT_DIR, accountId, templateId, templateUniqueName), S3Utils.SEPARATOR); } @SuppressWarnings("unchecked") private String determineS3TemplateNameFromKey(String key) { - return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR); + return StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), + S3Utils.SEPARATOR); } @SuppressWarnings("unchecked") @@ -454,7 +465,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S @SuppressWarnings("unchecked") protected Long determineS3VolumeIdFromKey(String key) { - return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), S3Utils.SEPARATOR)); + return Long.parseLong(StringUtils.substringAfterLast(StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR), + S3Utils.SEPARATOR)); } @SuppressWarnings("unchecked") @@ -482,7 +494,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String lPath = lDir + "/" + path; result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath); if (result != null) { - errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result; + errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + + " , err=" + result; s_logger.warn(errMsg); throw new CloudRuntimeException(errMsg); } @@ -490,7 +503,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S lPath = lDir + "/" + path; result = swiftDownload(swift, "T-" + templateId.toString(), path, lPath); if (result != null) { - errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + " , err=" + result; + errMsg = "failed to download template " + path + " from Swift to secondary storage " + lPath + + " , err=" + result; s_logger.warn(errMsg); throw new CloudRuntimeException(errMsg); } @@ -511,55 +525,40 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S return _dlMgr.handleDownloadCommand(this, cmd); } /* - else if (dstore instanceof S3TO) { - // TODO: start download job to handle this - // TODO: how to handle download progress for S3 - S3TO s3 = (S3TO) cmd.getDataStore(); - String url = cmd.getUrl(); - String user = null; - String password = null; - if (cmd.getAuth() != null) { - user = cmd.getAuth().getUserName(); - password = new String(cmd.getAuth().getPassword()); - } - // get input stream from the given url - InputStream in = UriUtils.getInputStreamFromUrl(url, user, password); - URI uri; - URL urlObj; - try { - uri = new URI(url); - urlObj = new URL(url); - } catch (URISyntaxException e) { - throw new CloudRuntimeException("URI is incorrect: " + url); - } catch (MalformedURLException e) { - throw new CloudRuntimeException("URL is incorrect: " + url); - } - - final String bucket = s3.getBucketName(); - String path = null; - if (cmd.getResourceType() == ResourceType.TEMPLATE) { - // convention is no / in the end for install path based on - // S3Utils implementation. - // template key is - // TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by - // adding template_name in the key, I can avoid generating a - // template.properties file - // for listTemplateCommand. - path = determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), cmd.getName()); - } else { - path = determineS3VolumeDirectory(cmd.getAccountId(), cmd.getResourceId()); - } - - String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR); - S3Utils.putObject(s3, in, bucket, key); - List s3Obj = S3Utils.getDirectory(s3, bucket, path); - if (s3Obj == null || s3Obj.size() == 0) { - return new Answer(cmd, false, "Failed to download to S3 bucket: " + bucket + " with key: " + key); - } else { - return new DownloadAnswer(null, 100, null, Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), s3Obj.get(0).getSize(), s3Obj - .get(0).getETag()); - } - } */ + * else if (dstore instanceof S3TO) { // TODO: start download job to + * handle this // TODO: how to handle download progress for S3 S3TO s3 = + * (S3TO) cmd.getDataStore(); String url = cmd.getUrl(); String user = + * null; String password = null; if (cmd.getAuth() != null) { user = + * cmd.getAuth().getUserName(); password = new + * String(cmd.getAuth().getPassword()); } // get input stream from the + * given url InputStream in = UriUtils.getInputStreamFromUrl(url, user, + * password); URI uri; URL urlObj; try { uri = new URI(url); urlObj = + * new URL(url); } catch (URISyntaxException e) { throw new + * CloudRuntimeException("URI is incorrect: " + url); } catch + * (MalformedURLException e) { throw new + * CloudRuntimeException("URL is incorrect: " + url); } + * + * final String bucket = s3.getBucketName(); String path = null; if + * (cmd.getResourceType() == ResourceType.TEMPLATE) { // convention is + * no / in the end for install path based on // S3Utils implementation. + * // template key is // + * TEMPLATE_ROOT_DIR/account_id/template_id/template_name, by // adding + * template_name in the key, I can avoid generating a // + * template.properties file // for listTemplateCommand. path = + * determineS3TemplateDirectory(cmd.getAccountId(), cmd.getResourceId(), + * cmd.getName()); } else { path = + * determineS3VolumeDirectory(cmd.getAccountId(), cmd.getResourceId()); + * } + * + * String key = join(asList(path, urlObj.getFile()), S3Utils.SEPARATOR); + * S3Utils.putObject(s3, in, bucket, key); List s3Obj = + * S3Utils.getDirectory(s3, bucket, path); if (s3Obj == null || + * s3Obj.size() == 0) { return new Answer(cmd, false, + * "Failed to download to S3 bucket: " + bucket + " with key: " + key); + * } else { return new DownloadAnswer(null, 100, null, + * Status.DOWNLOADED, path, path, s3Obj.get(0).getSize(), + * s3Obj.get(0).getSize(), s3Obj .get(0).getETag()); } } + */ else if (dstore instanceof SwiftTO) { // TODO: need to move code from // execute(uploadTemplateToSwiftFromSecondaryStorageCommand) here, @@ -588,7 +587,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } String result = swiftUpload(swift, "T-" + templateId.toString(), lPath, "*"); if (result != null) { - String errMsg = "failed to upload template from secondary storage " + lPath + " to swift , err=" + result; + String errMsg = "failed to upload template from secondary storage " + lPath + " to swift , err=" + + result; s_logger.debug(errMsg); return new Answer(cmd, false, errMsg); } @@ -638,7 +638,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S final String templatePath = determineStorageTemplatePath(srcStore.getUrl(), srcData.getPath()); if (s_logger.isDebugEnabled()) { - s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + " to upload to S3."); + s_logger.debug("Found " + srcData.getObjectType() + " from directory " + templatePath + + " to upload to S3."); } final String bucket = s3.getBucketName(); @@ -671,8 +672,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String swiftDownload(SwiftTO swift, String container, String rfilename, String lFullPath) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() - + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container + " " + rfilename + " -o " + lFullPath); + command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + + container + " " + rfilename + " -o " + lFullPath); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -697,8 +699,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String swiftDownloadContainer(SwiftTO swift, String container, String ldir) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " - + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " download " + container); + command.add("cd " + ldir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + + " download " + container); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -741,12 +744,15 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); command.add("-c"); if (size <= SWIFT_MAX_SIZE) { - command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " - + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload " + container + " " + file); + command.add("cd " + lDir + + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + + swift.getKey() + " upload " + container + " " + file); } else { - command.add("cd " + lDir + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " - + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container - + " " + file); + command.add("cd " + lDir + + ";/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + + swift.getUrl() + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + + swift.getKey() + " upload -S " + SWIFT_MAX_SIZE + " " + container + " " + file); } OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); @@ -773,8 +779,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String[] swiftList(SwiftTO swift, String container, String rFilename) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() - + ":" + swift.getUserName() + " -K " + swift.getKey() + " list " + container + " " + rFilename); + command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " list " + + container + " " + rFilename); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result == null && parser.getLines() != null) { @@ -795,8 +802,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S String swiftDelete(SwiftTO swift, String container, String object) { Script command = new Script("/bin/bash", s_logger); command.add("-c"); - command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + " -U " + swift.getAccount() - + ":" + swift.getUserName() + " -K " + swift.getKey() + " delete " + container + " " + object); + command.add("/usr/bin/python /usr/local/cloud/systemvm/scripts/storage/secondary/swift -A " + swift.getUrl() + + " -U " + swift.getAccount() + ":" + swift.getUserName() + " -K " + swift.getKey() + " delete " + + container + " " + object); OutputInterpreter.AllLinesParser parser = new OutputInterpreter.AllLinesParser(); String result = command.execute(parser); if (result != null) { @@ -849,7 +857,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } // delete the directory if (!snapshotDir.delete()) { - details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + relativeSnapshotPath; + details = "Unable to delete directory " + snapshotDir.getName() + " under snapshot path " + + relativeSnapshotPath; s_logger.debug(details); return new Answer(cmd, false, details); } @@ -862,7 +871,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S S3Utils.deleteDirectory(s3, bucket, path); return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, + final String errorMessage = String.format( + "Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); @@ -906,30 +916,35 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S @Override public Void call() throws Exception { - final String directoryName = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, volumeId); + final String directoryName = determineSnapshotLocalDirectory(secondaryStorageUrl, accountId, + volumeId); String result = createLocalDir(directoryName); if (result != null) { - throw new InternalErrorException(format("Failed to create directory %1$s during S3 snapshot download.", directoryName)); + throw new InternalErrorException(format( + "Failed to create directory %1$s during S3 snapshot download.", directoryName)); } final String snapshotFileName = determineSnapshotBackupFilename(cmd.getSnapshotUuid()); final String key = determineSnapshotS3Key(accountId, volumeId, snapshotFileName); - final File targetFile = S3Utils.getFile(s3, s3.getBucketName(), key, _storage.getFile(directoryName), new FileNamingStrategy() { + final File targetFile = S3Utils.getFile(s3, s3.getBucketName(), key, + _storage.getFile(directoryName), new FileNamingStrategy() { - @Override - public String determineFileName(String key) { - return snapshotFileName; - } + @Override + public String determineFileName(String key) { + return snapshotFileName; + } - }); + }); if (cmd.getParent() != null) { - final String parentPath = join(File.pathSeparator, directoryName, determineSnapshotBackupFilename(cmd.getParent())); + final String parentPath = join(File.pathSeparator, directoryName, + determineSnapshotBackupFilename(cmd.getParent())); result = setVhdParent(targetFile.getAbsolutePath(), parentPath); if (result != null) { - throw new InternalErrorException(format("Failed to set the parent for backup %1$s to %2$s due to %3$s.", + throw new InternalErrorException(format( + "Failed to set the parent for backup %1$s to %2$s due to %3$s.", targetFile.getAbsolutePath(), parentPath, result)); } @@ -941,12 +956,14 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S }); - return new Answer(cmd, true, format("Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.", volumeId, accountId, + return new Answer(cmd, true, format( + "Succesfully retrieved volume id %1$s for account id %2$s to %3$s from S3.", volumeId, accountId, secondaryStorageUrl)); } catch (Exception e) { - final String errMsg = format("Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s", volumeId, - accountId, secondaryStorageUrl, e.getMessage()); + final String errMsg = format( + "Failed to retrieve volume id %1$s for account id %2$s to %3$s from S3 due to exception %4$s", + volumeId, accountId, secondaryStorageUrl, e.getMessage()); s_logger.error(errMsg); return new Answer(cmd, false, errMsg); } @@ -964,7 +981,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, final Long volumeId) { + private String determineSnapshotLocalDirectory(final String secondaryStorageUrl, final Long accountId, + final Long volumeId) { return join(File.pathSeparator, getRootDir(secondaryStorageUrl), SNAPSHOT_ROOT_DIR, accountId, volumeId); } @@ -1149,8 +1167,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, final Long volumeId, - final String name, final Boolean deleteAllFlag) { + private String deleteSnapshotBackupFromLocalFileSystem(final String secondaryStorageUrl, final Long accountId, + final Long volumeId, final String name, final Boolean deleteAllFlag) { String lPath = null; int index = name.lastIndexOf(File.separator); String snapshotPath = name.substring(0, index); @@ -1170,34 +1188,41 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - private String deleteSnapshotBackupfromS3(final S3TO s3, final Long accountId, final Long volumeId, final String name, final Boolean deleteAllFlag) { + private String deleteSnapshotBackupfromS3(final S3TO s3, final Long accountId, final Long volumeId, + final String name, final Boolean deleteAllFlag) { try { final String bucket = s3.getBucketName(); - final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), new Callable() { + final String result = executeWithNoWaitLock(determineSnapshotLockId(accountId, volumeId), + new Callable() { - @Override - public String call() throws Exception { + @Override + public String call() throws Exception { - if (deleteAllFlag) { - S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId)); - } else { - S3Utils.deleteObject(s3, bucket, determineSnapshotS3Key(accountId, volumeId, determineSnapshotBackupFilename(name))); - } + if (deleteAllFlag) { + S3Utils.deleteDirectory(s3, bucket, determineSnapshotS3Directory(accountId, volumeId)); + } else { + S3Utils.deleteObject( + s3, + bucket, + determineSnapshotS3Key(accountId, volumeId, + determineSnapshotBackupFilename(name))); + } - return null; + return null; - } + } - }); + }); return result; } catch (Exception e) { - s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", accountId, volumeId), e); + s_logger.error(String.format("Failed to delete snapshot backup for account id %1$s volume id %2$sfrom S3.", + accountId, volumeId), e); return e.getMessage(); } @@ -1237,7 +1262,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!snapshot.delete()) { - return new Answer(cmd, false, "Unable to delete file " + snapshot.getName() + " under install path " + relativeSnapshotPath); + return new Answer(cmd, false, "Unable to delete file " + snapshot.getName() + " under install path " + + relativeSnapshotPath); } return new Answer(cmd, true, null); @@ -1249,7 +1275,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S S3Utils.deleteObject(s3, bucket, path); return new Answer(cmd, true, String.format("Deleted snapshot %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String.format("Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, + final String errorMessage = String.format( + "Failed to delete snapshot %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); @@ -1281,7 +1308,6 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } - Map swiftListTemplate(SwiftTO swift) { String[] containers = swiftList(swift, "", ""); if (containers == null) { @@ -1324,10 +1350,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Map tmpltInfos = new HashMap(); for (S3ObjectSummary objectSummary : objectSummaries) { String key = objectSummary.getKey(); - //String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); + // String installPath = StringUtils.substringBeforeLast(key, + // S3Utils.SEPARATOR); String uniqueName = this.determineS3TemplateNameFromKey(key); // TODO: isPublic value, where to get? - TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), true, false); + TemplateProp tInfo = new TemplateProp(uniqueName, key, objectSummary.getSize(), objectSummary.getSize(), + true, false); tmpltInfos.put(uniqueName, tInfo); } return tmpltInfos; @@ -1343,10 +1371,12 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Map tmpltInfos = new HashMap(); for (S3ObjectSummary objectSummary : objectSummaries) { String key = objectSummary.getKey(); - //String installPath = StringUtils.substringBeforeLast(key, S3Utils.SEPARATOR); + // String installPath = StringUtils.substringBeforeLast(key, + // S3Utils.SEPARATOR); Long id = this.determineS3VolumeIdFromKey(key); // TODO: how to get volume template name - TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), true, false); + TemplateProp tInfo = new TemplateProp(id.toString(), key, objectSummary.getSize(), objectSummary.getSize(), + true, false); tmpltInfos.put(id, tInfo); } return tmpltInfos; @@ -1407,8 +1437,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S for (String cidr : cmd.getAllowedInternalSites()) { if (nfsIps.contains(cidr)) { /* - * if the internal download ip is the same with secondary storage ip, adding internal sites will flush - * ip route to nfs through storage ip. + * if the internal download ip is the same with secondary + * storage ip, adding internal sites will flush ip route to nfs + * through storage ip. */ continue; } @@ -1490,7 +1521,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S Script command = new Script("/bin/bash", s_logger); String intf = "eth1"; command.add("-c"); - command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + " -p tcp -m state --state NEW -m tcp -j ACCEPT"); + command.add("iptables -I OUTPUT -o " + intf + " -d " + destCidr + + " -p tcp -m state --state NEW -m tcp -j ACCEPT"); String result = command.execute(); if (result != null) { @@ -1535,10 +1567,10 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } - protected Answer execute(final DeleteCommand cmd){ + protected Answer execute(final DeleteCommand cmd) { DataTO obj = cmd.getData(); DataObjectType objType = obj.getObjectType(); - switch (objType){ + switch (objType) { case TEMPLATE: return deleteTemplate(cmd); case VOLUME: @@ -1595,7 +1627,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!f.delete()) { - return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath); + return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + + relativeTemplatePath); } } @@ -1605,7 +1638,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } if (!tmpltParent.delete()) { - details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath; + details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + + relativeTemplatePath; s_logger.debug(details); return new Answer(cmd, false, details); } @@ -1618,7 +1652,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S S3Utils.deleteDirectory(s3, bucket, path); return new Answer(cmd, true, String.format("Deleted template %1$s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String.format("Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, + final String errorMessage = String.format( + "Failed to delete template %1$s from bucket %2$s due to the following error: %3$s", path, bucket, e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); @@ -1692,7 +1727,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } if (!f.delete()) { - return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + relativeVolumePath); + return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Volume path " + + relativeVolumePath); } } if (!found) { @@ -1701,7 +1737,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S } } if (!tmpltParent.delete()) { - details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + relativeVolumePath; + details = "Unable to delete directory " + tmpltParent.getName() + " under Volume path " + + relativeVolumePath; s_logger.debug(details); return new Answer(cmd, false, details); } @@ -1714,8 +1751,9 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S S3Utils.deleteDirectory(s3, bucket, path); return new Answer(cmd, true, String.format("Deleted volume %1%s from bucket %2$s.", path, bucket)); } catch (Exception e) { - final String errorMessage = String.format("Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, - bucket, e.getMessage()); + final String errorMessage = String.format( + "Failed to delete volume %1$s from bucket %2$s due to the following error: %3$s", path, bucket, + e.getMessage()); s_logger.error(errorMessage, e); return new Answer(cmd, false, errorMessage); } @@ -1880,9 +1918,11 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr); } - createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh"); + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), + "create_privatetemplate_from_snapshot_xen.sh"); if (createTemplateFromSnapshotXenScript == null) { - throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir()); + throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + + getDefaultScriptsDir()); } _role = (String) params.get("role"); @@ -1969,7 +2009,8 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (!_inSystemVM) { return; } - s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + ",destIp=" + destIpOrCidr); + s_logger.debug("addRouteToInternalIp: localgw=" + localgw + ", eth1ip=" + eth1ip + ", eth1mask=" + eth1mask + + ",destIp=" + destIpOrCidr); if (destIpOrCidr == null) { s_logger.debug("addRouteToInternalIp: destIp is null"); return; @@ -1983,14 +2024,16 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S if (eth1ip != null && eth1mask != null) { inSameSubnet = NetUtils.sameSubnet(eth1ip, destIpOrCidr, eth1mask); } else { - s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + destIpOrCidr - + ", _eth1mask=" + eth1mask); + s_logger.warn("addRouteToInternalIp: unable to determine same subnet: _eth1ip=" + eth1ip + ", dest ip=" + + destIpOrCidr + ", _eth1mask=" + eth1mask); } } else { - inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask)); + inSameSubnet = NetUtils.isNetworkAWithinNetworkB(destIpOrCidr, + NetUtils.ipAndNetMaskToCidr(eth1ip, eth1mask)); } if (inSameSubnet) { - s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + eth1ip); + s_logger.debug("addRouteToInternalIp: dest ip " + destIpOrCidr + " is in the same subnet as eth1 ip " + + eth1ip); return; } Script command = new Script("/bin/bash", s_logger); From 1df4cf839e05970e45b9979951cdb66c2feb1f5b Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 17 Jun 2013 11:49:33 -0700 Subject: [PATCH 298/303] CLOUDSTACK-3028: Object_Store_Refactor - S3 reduced redundancy storage should be an option. --- api/src/com/cloud/agent/api/to/S3TO.java | 18 +++++++++++++++++- .../storage/template/S3TemplateDownloader.java | 7 +++++-- .../driver/S3ImageStoreDriverImpl.java | 9 ++++++++- server/src/com/cloud/configuration/Config.java | 18 ++++++++++-------- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/S3TO.java b/api/src/com/cloud/agent/api/to/S3TO.java index 10207288185..8a2f09dc5ab 100644 --- a/api/src/com/cloud/agent/api/to/S3TO.java +++ b/api/src/com/cloud/agent/api/to/S3TO.java @@ -34,6 +34,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { private Integer maxErrorRetry; private Integer socketTimeout; private Date created; + private boolean enableRRS; public S3TO() { @@ -45,7 +46,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { final String secretKey, final String endPoint, final String bucketName, final Boolean httpsFlag, final Integer connectionTimeout, final Integer maxErrorRetry, - final Integer socketTimeout, final Date created) { + final Integer socketTimeout, final Date created, final boolean enableRRS) { super(); @@ -60,6 +61,7 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { this.maxErrorRetry = maxErrorRetry; this.socketTimeout = socketTimeout; this.created = created; + this.enableRRS = enableRRS; } @@ -129,6 +131,10 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { return false; } + if (enableRRS != thatS3TO.enableRRS) { + return false; + } + return true; } @@ -256,4 +262,14 @@ public final class S3TO implements S3Utils.ClientOptions, DataStoreTO { } + + public boolean getEnableRRS() { + return enableRRS; + } + + public void setEnableRRS(boolean enableRRS) { + this.enableRRS = enableRRS; + } + + } diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index ca0df5d515e..7763423a4a0 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -225,8 +225,11 @@ public class S3TemplateDownloader implements TemplateDownloader { // download using S3 API ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(remoteSize); - PutObjectRequest putObjectRequest = new PutObjectRequest(s3.getBucketName(), s3Key, in, metadata) - .withStorageClass(StorageClass.ReducedRedundancy); + PutObjectRequest putObjectRequest = new PutObjectRequest(s3.getBucketName(), s3Key, in, metadata); + // check if RRS is enabled + if (s3.getEnableRRS()){ + putObjectRequest = putObjectRequest.withStorageClass(StorageClass.ReducedRedundancy); + } // register progress listenser putObjectRequest.setProgressListener(new ProgressListener() { @Override diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 49da980dfd8..850c42b96a9 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -31,6 +31,8 @@ import org.apache.log4j.Logger; import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; +import com.cloud.configuration.Config; +import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.S3Utils; import com.cloud.utils.exception.CloudRuntimeException; @@ -41,6 +43,9 @@ public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl { @Inject ImageStoreDetailsDao _imageStoreDetailsDao; + @Inject + ConfigurationDao _configDao; + @Override public DataStoreTO getStoreTO(DataStore store) { @@ -55,7 +60,9 @@ public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl { details.get(ApiConstants.S3_MAX_ERROR_RETRY) == null ? null : Integer.valueOf(details .get(ApiConstants.S3_MAX_ERROR_RETRY)), details.get(ApiConstants.S3_SOCKET_TIMEOUT) == null ? null : Integer.valueOf(details - .get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated()); + .get(ApiConstants.S3_SOCKET_TIMEOUT)), imgStore.getCreated(), + _configDao.getValue(Config.S3EnableRRS.toString()) == null ? false : Boolean.parseBoolean(_configDao + .getValue(Config.S3EnableRRS.toString()))); } diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 6bad4176da5..219bed07191 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -144,7 +144,7 @@ public enum Config { SnapshotPollInterval("Snapshots", SnapshotManager.class, Integer.class, "snapshot.poll.interval", "300", "The time interval in seconds when the management server polls for snapshots to be scheduled.", null), SnapshotDeltaMax("Snapshots", SnapshotManager.class, Integer.class, "snapshot.delta.max", "16", "max delta snapshots between two full snapshots.", null), BackupSnapshotAferTakingSnapshot("Snapshots", SnapshotManager.class, Boolean.class, "snapshot.backup.rightafter", "true", "backup snapshot right after snapshot is taken", null), - + // Advanced JobExpireMinutes("Advanced", ManagementServer.class, String.class, "job.expire.minutes", "1440", "Time (in minutes) for async-jobs to be kept in system", null), JobCancelThresholdMinutes("Advanced", ManagementServer.class, String.class, "job.cancel.threshold.minutes", "60", "Time (in minutes) for async-jobs to be forcely cancelled if it has been in process for long", null), @@ -219,7 +219,7 @@ public enum Config { AlertPurgeInterval("Advanced", ManagementServer.class, Integer.class, "alert.purge.interval", "86400", "The interval (in seconds) to wait before running the alert purge thread", null), AlertPurgeDelay("Advanced", ManagementServer.class, Integer.class, "alert.purge.delay", "0", "Alerts older than specified number days will be purged. Set this value to 0 to never delete alerts", null), HostReservationReleasePeriod("Advanced", ManagementServer.class, Integer.class, "host.reservation.release.period", "300000", "The interval in milliseconds between host reservation release checks", null), - + // LB HealthCheck Interval. LBHealthCheck("Advanced", ManagementServer.class, String.class, "healthcheck.update.interval", "600", @@ -408,20 +408,22 @@ public enum Config { ApiLimitMax("Advanced", ManagementServer.class, Integer.class, "api.throttling.max", "25", "Max allowed number of APIs within fixed interval", null), ApiLimitCacheSize("Advanced", ManagementServer.class, Integer.class, "api.throttling.cachesize", "50000", "Account based API count cache size", null), - + // object store + S3EnableRRS("Advanced", ManagementServer.class, Boolean.class, "s3.rrs.enabled", "false", "enable s3 reduced redundancy storage", null), + // VMSnapshots VMSnapshotMax("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.max", "10", "Maximum vm snapshots for a vm", null), VMSnapshotCreateWait("Advanced", VMSnapshotManager.class, Integer.class, "vmsnapshot.create.wait", "1800", "In second, timeout for create vm snapshot", null), CloudDnsName("Advanced", ManagementServer.class, String.class, "cloud.dns.name", null, "DNS name of the cloud for the GSLB service", null), - + BlacklistedRoutes("Advanced", VpcManager.class, String.class, "blacklisted.routes", null, "Routes that are blacklisted, can not be used for Static Routes creation for the VPC Private Gateway", "routes", ConfigurationParameterScope.zone.toString()), - + InternalLbVmServiceOfferingId("Advanced", ManagementServer.class, Long.class, "internallbvm.service.offering", null, "Uuid of the service offering used by internal lb vm; if NULL - default system internal lb offering will be used", null); - - - + + + private final String _category; private final Class _componentClass; private final Class _type; From cf43344541c750a877775b0efb4acf1dca5fd00b Mon Sep 17 00:00:00 2001 From: Min Chen Date: Mon, 17 Jun 2013 13:48:02 -0700 Subject: [PATCH 299/303] Fix build error --- engine/schema/src/com/cloud/storage/S3VO.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/engine/schema/src/com/cloud/storage/S3VO.java b/engine/schema/src/com/cloud/storage/S3VO.java index 6b2c23fc1ae..e30da0cbc2d 100644 --- a/engine/schema/src/com/cloud/storage/S3VO.java +++ b/engine/schema/src/com/cloud/storage/S3VO.java @@ -30,6 +30,7 @@ import javax.persistence.Table; import com.cloud.agent.api.to.S3TO; import com.cloud.utils.db.GenericDao; +//TODO: this will be removed after object_store merge. @Entity @Table(name = "s3") public class S3VO implements S3 { @@ -109,7 +110,7 @@ public class S3VO implements S3 { } return new S3TO(this.id, this.uuid, this.accessKey, this.secretKey, this.endPoint, this.bucketName, httpsFlag, - this.connectionTimeout, this.maxErrorRetry, this.socketTimeout, this.created); + this.connectionTimeout, this.maxErrorRetry, this.socketTimeout, this.created, false); } From 1eb39665bd802577f7d925c9703fcd0549996329 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Tue, 18 Jun 2013 09:45:50 -0700 Subject: [PATCH 300/303] CLOUDSTACK-3030: Object_Store_Refactor - Download template from S3 should not set template to public-readable. --- .../driver/S3ImageStoreDriverImpl.java | 29 +++++++++---------- utils/src/com/cloud/utils/S3Utils.java | 14 +++++++++ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 850c42b96a9..85547ff2e6f 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -18,6 +18,8 @@ */ package org.apache.cloudstack.storage.datastore.driver; +import java.net.URL; +import java.util.Date; import java.util.Map; import javax.inject.Inject; @@ -28,14 +30,12 @@ import org.apache.cloudstack.storage.image.BaseImageStoreDriverImpl; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.log4j.Logger; -import com.amazonaws.services.s3.model.CannedAccessControlList; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.configuration.Config; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.S3Utils; -import com.cloud.utils.exception.CloudRuntimeException; public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl { private static final Logger s_logger = Logger.getLogger(S3ImageStoreDriverImpl.class); @@ -74,20 +74,17 @@ public class S3ImageStoreDriverImpl extends BaseImageStoreDriverImpl { // make the url accessible S3TO s3 = (S3TO)getStoreTO(store); String key = installPath; - try { - S3Utils.setObjectAcl(s3, s3.getBucketName(), key, CannedAccessControlList.PublicRead); - } catch (Exception ex) { - s_logger.error("Failed to set ACL on S3 object " + key + " to PUBLIC_READ", ex); - throw new CloudRuntimeException("Failed to set ACL on S3 object " + key + " to PUBLIC_READ"); - } - // construct the url from s3 - StringBuffer s3url = new StringBuffer(); - s3url.append(s3.isHttps() ? "https://" : "http://"); - s3url.append(s3.getEndPoint()); - s3url.append("/"); - s3url.append(s3.getBucketName()); - s3url.append("/"); - s3url.append(key); + + s_logger.info("Generating pre-signed s3 entity extraction URL."); + Date expiration = new Date(); + long milliSeconds = expiration.getTime(); + milliSeconds += 1000 * 60 * 60; // expired after one hour. + expiration.setTime(milliSeconds); + + URL s3url = S3Utils.generatePresignedUrl(s3, s3.getBucketName(), key, expiration); + + s_logger.info("Pre-Signed URL = " + s3url.toString()); + return s3url.toString(); } diff --git a/utils/src/com/cloud/utils/S3Utils.java b/utils/src/com/cloud/utils/S3Utils.java index e7817f5a57c..0a4a4430cd5 100644 --- a/utils/src/com/cloud/utils/S3Utils.java +++ b/utils/src/com/cloud/utils/S3Utils.java @@ -38,7 +38,9 @@ import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; +import java.net.URL; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.UUID; @@ -47,6 +49,7 @@ import org.apache.log4j.Logger; import com.amazonaws.AmazonClientException; import com.amazonaws.ClientConfiguration; +import com.amazonaws.HttpMethod; import com.amazonaws.auth.AWSCredentials; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3; @@ -178,6 +181,17 @@ public final class S3Utils { } + public static URL generatePresignedUrl(final ClientOptions clientOptions, final String bucketName, final String key, + final Date expiration) { + + assert clientOptions != null; + assert !isBlank(bucketName); + assert !isBlank(key); + + return acquireClient(clientOptions).generatePresignedUrl(bucketName, key, expiration, HttpMethod.GET); + + } + // Note that whenever S3Object is returned, client code needs to close the internal stream to avoid resource leak. public static S3Object getObject(final ClientOptions clientOptions, final String bucketName, final String key) { From 0dd14b1c6152700ff7f1f433eed6f3ce76cdfc61 Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Wed, 19 Jun 2013 12:24:36 -0700 Subject: [PATCH 301/303] Secondary storage listView: Add image stores dummy section --- ui/scripts/system.js | 1667 ++++++++++++++++++++++++++++-------------- 1 file changed, 1115 insertions(+), 552 deletions(-) diff --git a/ui/scripts/system.js b/ui/scripts/system.js index a3db63a7055..0d5e212b061 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -6517,51 +6517,55 @@ return listView; }, secondaryStorage: function() { - var listView = $.extend(true, {}, cloudStack.sections.system.subsections['secondary-storage'].listView, { - dataProvider: function (args) { - var searchByArgs = args.filterBy.search.value.length ? - '&name=' + args.filterBy.search.value : ''; + var listView = $.extend( + true, {}, + cloudStack.sections.system.subsections['secondary-storage'].sections.secondaryStorage, { + listView: { + dataProvider: function (args) { + var searchByArgs = args.filterBy.search.value.length ? + '&name=' + args.filterBy.search.value : ''; - var data = { - type: 'SecondaryStorage', - page: args.page, - pageSize: pageSize, - listAll: true - }; + var data = { + type: 'SecondaryStorage', + page: args.page, + pageSize: pageSize, + listAll: true + }; - $.ajax({ - url: createURL('listImageStores' + searchByArgs), - data: data, - success: function (json) { - args.response.success({ data: json.listimagestoreresponse.imagestore }); + $.ajax({ + url: createURL('listImageStores' + searchByArgs), + data: data, + success: function (json) { + args.response.success({ data: json.listimagestoreresponse.imagestore }); + }, + error: function (json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); }, - error: function (json) { - args.response.error(parseXMLHttpResponse(json)); - } - }); - }, + detailView: { + updateContext: function (args) { + var zone; - detailView: { - updateContext: function (args) { - var zone; + $.ajax({ + url: createURL('listZones'), + data: { id: args.context.secondarystorages[0].zoneid }, + async: false, + success: function (json) { + zone = json.listzonesresponse.zone[0]; + } + }); - $.ajax({ - url: createURL('listZones'), - data: { id: args.context.secondarystorages[0].zoneid }, - async: false, - success: function (json) { - zone = json.listzonesresponse.zone[0]; + selectedZoneObj = zone; + + return { + zones: [zone] + }; } - }); - - selectedZoneObj = zone; - - return { - zones: [zone] - }; + } } } - }); + ); return listView; }, @@ -12356,549 +12360,1108 @@ 'secondary-storage': { title: 'label.secondary.storage', id: 'secondarystorages', - listView: { - id: 'secondarystorages', - section: 'seconary-storage', - fields: { - name: { label: 'label.name' }, - url: { label: 'label.url' }, - providername: { label: 'Provider' } - }, + sectionSelect: { + label: 'label.select.view' + }, + sections: { + secondaryStorage: { + type: 'select', + title: 'label.secondary.storage', + listView: { + id: 'secondarystorages', + section: 'seconary-storage', + fields: { + name: { label: 'label.name' }, + url: { label: 'label.url' }, + providername: { label: 'Provider' } + }, - dataProvider: function(args) { - var array1 = []; - if(args.filterBy != null) { - if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { - switch(args.filterBy.search.by) { - case "name": - if(args.filterBy.search.value.length > 0) - array1.push("&keyword=" + args.filterBy.search.value); - break; - } - } - } - array1.push("&zoneid=" + args.context.zones[0].id); + dataProvider: function(args) { + var array1 = []; + if(args.filterBy != null) { + if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch(args.filterBy.search.by) { + case "name": + if(args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; + } + } + } + array1.push("&zoneid=" + args.context.zones[0].id); - $.ajax({ - url: createURL("listImageStores&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), - dataType: "json", - async: true, - success: function(json) { - var items = json.listimagestoreresponse.imagestore; - args.response.success({ - actionFilter: secondarystorageActionfilter, - data:items + $.ajax({ + url: createURL("listImageStores&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, + success: function(json) { + var items = json.listimagestoreresponse.imagestore; + args.response.success({ + actionFilter: secondarystorageActionfilter, + data:items + }); + } }); - } - }); - }, + }, - actions: { - add: { - label: 'label.add.secondary.storage', + actions: { + add: { + label: 'label.add.secondary.storage', - createForm: { - title: 'label.add.secondary.storage', - - fields: { - name: { label: 'label.name' }, - provider: { - label: 'Provider', - select: function(args){ - $.ajax({ - url: createURL('listStorageProviders'), - data: { - type: 'image' - }, - success: function(json){ - var objs = json.liststorageprovidersresponse.dataStoreProvider; - var items = []; - if(objs != null) { - for(var i = 0; i < objs.length; i++){ - if(objs[i].name == 'NFS') - items.unshift({id: objs[i].name, description: objs[i].name}); - else - items.push({id: objs[i].name, description: objs[i].name}); - } - } - args.response.success({ - data: items + createForm: { + title: 'label.add.secondary.storage', + + fields: { + name: { label: 'label.name' }, + provider: { + label: 'Provider', + select: function(args){ + $.ajax({ + url: createURL('listStorageProviders'), + data: { + type: 'image' + }, + success: function(json){ + var objs = json.liststorageprovidersresponse.dataStoreProvider; + var items = []; + if(objs != null) { + for(var i = 0; i < objs.length; i++){ + if(objs[i].name == 'NFS') + items.unshift({id: objs[i].name, description: objs[i].name}); + else + items.push({id: objs[i].name, description: objs[i].name}); + } + } + args.response.success({ + data: items + }); + + args.$select.change(function() { + var $form = $(this).closest('form'); + if($(this).val() == "NFS") { + //NFS + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if ($(this).val() == "S3") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); + $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); + $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); + $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); + $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); + $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + + $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked','checked'); + $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); + + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if($(this).val() == "Swift") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + + //Swift + $form.find('.form-item[rel=url]').css('display', 'inline-block'); + $form.find('.form-item[rel=account]').css('display', 'inline-block'); + $form.find('.form-item[rel=username]').css('display', 'inline-block'); + $form.find('.form-item[rel=key]').css('display', 'inline-block'); + } + }); + + args.$select.change(); + } }); - - args.$select.change(function() { - var $form = $(this).closest('form'); - if($(this).val() == "NFS") { - //NFS - $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); - $form.find('.form-item[rel=path]').css('display', 'inline-block'); - - //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); - - $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); - $form.find('.form-item[rel=createNfsCache]').hide(); - $form.find('.form-item[rel=nfsCacheZoneid]').hide(); - $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); - $form.find('.form-item[rel=nfsCachePath]').hide(); - - //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); - } - else if ($(this).val() == "S3") { - //NFS - $form.find('.form-item[rel=zoneid]').hide(); - $form.find('.form-item[rel=nfsServer]').hide(); - $form.find('.form-item[rel=path]').hide(); - - //S3 - $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); - $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); - $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); - $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); - $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); - $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); - $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); - $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); - - $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked','checked'); - $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); - $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); - - - //Swift - $form.find('.form-item[rel=url]').hide(); - $form.find('.form-item[rel=account]').hide(); - $form.find('.form-item[rel=username]').hide(); - $form.find('.form-item[rel=key]').hide(); - } - else if($(this).val() == "Swift") { - //NFS - $form.find('.form-item[rel=zoneid]').hide(); - $form.find('.form-item[rel=nfsServer]').hide(); - $form.find('.form-item[rel=path]').hide(); - - //S3 - $form.find('.form-item[rel=accesskey]').hide(); - $form.find('.form-item[rel=secretkey]').hide(); - $form.find('.form-item[rel=bucket]').hide(); - $form.find('.form-item[rel=endpoint]').hide(); - $form.find('.form-item[rel=usehttps]').hide(); - $form.find('.form-item[rel=connectiontimeout]').hide(); - $form.find('.form-item[rel=maxerrorretry]').hide(); - $form.find('.form-item[rel=sockettimeout]').hide(); - - $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); - $form.find('.form-item[rel=createNfsCache]').hide(); - $form.find('.form-item[rel=nfsCacheZoneid]').hide(); - $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); - $form.find('.form-item[rel=nfsCachePath]').hide(); - - //Swift - $form.find('.form-item[rel=url]').css('display', 'inline-block'); - $form.find('.form-item[rel=account]').css('display', 'inline-block'); - $form.find('.form-item[rel=username]').css('display', 'inline-block'); - $form.find('.form-item[rel=key]').css('display', 'inline-block'); - } - }); - - args.$select.change(); } - }); - } - }, - - - //NFS (begin) - zoneid: { - label: 'Zone', - docID: 'helpSecondaryStorageZone', - validation: { required: true }, - select: function(args) { - $.ajax({ - url: createURL('listZones'), - data: { - listAll: true - }, - success: function(json) { - var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : []; - - if(zones != null){ //$.map(items, fn) - items can not be null - args.response.success({ - data: $.map(zones, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); - } - else { - args.response.success({data: null}); - } - } - }); - } - }, - nfsServer: { - label: 'label.nfs.server', - docID: 'helpSecondaryStorageNFSServer', - validation: { required: true } - }, - path: { - label: 'label.path', - docID: 'helpSecondaryStoragePath', - validation: { required: true } - }, - //NFS (end) - - - //S3 (begin) - accesskey: { label: 'label.s3.access_key', validation: { required: true } }, - secretkey: { label: 'label.s3.secret_key', validation: { required: true} }, - bucket: { label: 'label.s3.bucket', validation: { required: true} }, - endpoint: { label: 'label.s3.endpoint' }, - usehttps: { - label: 'label.s3.use_https', - isEditable: true, - isBoolean: true, - isChecked: true, - converter:cloudStack.converters.toBooleanText - }, - connectiontimeout: { label: 'label.s3.connection_timeout' }, - maxerrorretry: { label: 'label.s3.max_error_retry' }, - sockettimeout: { label: 'label.s3.socket_timeout' }, - - createNfsCache: { - label: 'Create NFS Cache Storage', - isBoolean: true, - isChecked: true - }, - nfsCacheZoneid: { - dependsOn: 'createNfsCache', - label: 'Zone', - validation: { required: true }, - select: function(args) { - $.ajax({ - url: createURL('listZones'), - data: { - listAll: true - }, - success: function(json) { - var zones = json.listzonesresponse.zone; - - if(zones != null){ //$.map(items, fn) - items can not be null - args.response.success({ - data: $.map(zones, function(zone) { - return { - id: zone.id, - description: zone.name - }; - }) - }); - } - else { - args.response.success({data: null}); - } - } - }); - } - }, - nfsCacheNfsServer: { - dependsOn: 'createNfsCache', - label: 'label.nfs.server', - validation: { required: true } - }, - nfsCachePath: { - dependsOn: 'createNfsCache', - label: 'label.path', - validation: { required: true } - }, - //S3 (end) - - - //Swift (begin) - url: { label: 'label.url', validation: { required: true } }, - account: { label: 'label.account' }, - username: { label: 'label.username' }, - key: { label: 'label.key' } - //Swift (end) - } - }, - - action: function(args) { - var data = {}; - if(args.data.name != null && args.data.name.length > 0) { - $.extend(data, { - name: args.data.name - }); - } - - if(args.data.provider == 'NFS') { - var zoneid = args.data.zoneid; - var nfs_server = args.data.nfsServer; - var path = args.data.path; - var url = nfsURL(nfs_server, path); - - $.extend(data, { - provider: args.data.provider, - zoneid: zoneid, - url: url - }); - - $.ajax({ - url: createURL('addImageStore'), - data: data, - success: function(json) { - var item = json.addimagestoreresponse.secondarystorage; - args.response.success({ - data:item - }); - }, - error: function(XMLHttpResponse) { - var errorMsg = parseXMLHttpResponse(XMLHttpResponse); - args.response.error(errorMsg); - } - }); - } - else if(args.data.provider == 'S3') { - $.extend(data, { - provider: args.data.provider, - 'details[0].key': 'accesskey', - 'details[0].value': args.data.accesskey, - 'details[1].key': 'secretkey', - 'details[1].value': args.data.secretkey, - 'details[2].key': 'bucket', - 'details[2].value': args.data.bucket, - 'details[3].key': 'usehttps', - 'details[3].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false') - }); - - var index = 4; - if(args.data.endpoint != null && args.data.endpoint.length > 0){ - data['details[' + index.toString() + '].key'] = 'endpoint'; - data['details[' + index.toString() + '].value'] = args.data.endpoint; - index++; - } - if(args.data.connectiontimeout != null && args.data.connectiontimeout.length > 0){ - data['details[' + index.toString() + '].key'] = 'connectiontimeout'; - data['details[' + index.toString() + '].value'] = args.data.connectiontimeout; - index++; - } - if(args.data.maxerrorretry != null && args.data.maxerrorretry.length > 0){ - data['details[' + index.toString() + '].key'] = 'maxerrorretry'; - data['details[' + index.toString() + '].value'] = args.data.maxerrorretry; - index++; - } - if(args.data.sockettimeout != null && args.data.sockettimeout.length > 0){ - data['details[' + index.toString() + '].key'] = 'sockettimeout'; - data['details[' + index.toString() + '].value'] = args.data.sockettimeout; - index++; - } - - $.ajax({ - url: createURL('addImageStore'), - data: data, - success: function(json) { - havingS3 = true; - var item = json.addimagestoreresponse.secondarystorage; - args.response.success({ - data:item - }); - }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); - } - }); - - if(args.data.createNfsCache == 'on') { - var zoneid = args.data.nfsCacheZoneid; - var nfs_server = args.data.nfsCacheNfsServer; - var path = args.data.nfsCachePath; - var url = nfsURL(nfs_server, path); - - var nfsCacheData = { - provider: 'NFS', - zoneid: zoneid, - url: url - }; - - $.ajax({ - url: createURL('createCacheStore'), - data: nfsCacheData, - success: function(json) { - //do nothing }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); + + + //NFS (begin) + zoneid: { + label: 'Zone', + docID: 'helpSecondaryStorageZone', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : []; + + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } + } + }); + } + }, + nfsServer: { + label: 'label.nfs.server', + docID: 'helpSecondaryStorageNFSServer', + validation: { required: true } + }, + path: { + label: 'label.path', + docID: 'helpSecondaryStoragePath', + validation: { required: true } + }, + //NFS (end) + + + //S3 (begin) + accesskey: { label: 'label.s3.access_key', validation: { required: true } }, + secretkey: { label: 'label.s3.secret_key', validation: { required: true} }, + bucket: { label: 'label.s3.bucket', validation: { required: true} }, + endpoint: { label: 'label.s3.endpoint' }, + usehttps: { + label: 'label.s3.use_https', + isEditable: true, + isBoolean: true, + isChecked: true, + converter:cloudStack.converters.toBooleanText + }, + connectiontimeout: { label: 'label.s3.connection_timeout' }, + maxerrorretry: { label: 'label.s3.max_error_retry' }, + sockettimeout: { label: 'label.s3.socket_timeout' }, + + createNfsCache: { + label: 'Create NFS Cache Storage', + isBoolean: true, + isChecked: true + }, + nfsCacheZoneid: { + dependsOn: 'createNfsCache', + label: 'Zone', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } + } + }); + } + }, + nfsCacheNfsServer: { + dependsOn: 'createNfsCache', + label: 'label.nfs.server', + validation: { required: true } + }, + nfsCachePath: { + dependsOn: 'createNfsCache', + label: 'label.path', + validation: { required: true } + }, + //S3 (end) + + + //Swift (begin) + url: { label: 'label.url', validation: { required: true } }, + account: { label: 'label.account' }, + username: { label: 'label.username' }, + key: { label: 'label.key' } + //Swift (end) + } + }, + + action: function(args) { + var data = {}; + if(args.data.name != null && args.data.name.length > 0) { + $.extend(data, { + name: args.data.name + }); + } + + if(args.data.provider == 'NFS') { + var zoneid = args.data.zoneid; + var nfs_server = args.data.nfsServer; + var path = args.data.path; + var url = nfsURL(nfs_server, path); + + $.extend(data, { + provider: args.data.provider, + zoneid: zoneid, + url: url + }); + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + args.response.error(errorMsg); + } + }); + } + else if(args.data.provider == 'S3') { + $.extend(data, { + provider: args.data.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.bucket, + 'details[3].key': 'usehttps', + 'details[3].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false') + }); + + var index = 4; + if(args.data.endpoint != null && args.data.endpoint.length > 0){ + data['details[' + index.toString() + '].key'] = 'endpoint'; + data['details[' + index.toString() + '].value'] = args.data.endpoint; + index++; } - }); - } + if(args.data.connectiontimeout != null && args.data.connectiontimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'connectiontimeout'; + data['details[' + index.toString() + '].value'] = args.data.connectiontimeout; + index++; + } + if(args.data.maxerrorretry != null && args.data.maxerrorretry.length > 0){ + data['details[' + index.toString() + '].key'] = 'maxerrorretry'; + data['details[' + index.toString() + '].value'] = args.data.maxerrorretry; + index++; + } + if(args.data.sockettimeout != null && args.data.sockettimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'sockettimeout'; + data['details[' + index.toString() + '].value'] = args.data.sockettimeout; + index++; + } + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + havingS3 = true; + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + + if(args.data.createNfsCache == 'on') { + var zoneid = args.data.nfsCacheZoneid; + var nfs_server = args.data.nfsCacheNfsServer; + var path = args.data.nfsCachePath; + var url = nfsURL(nfs_server, path); + + var nfsCacheData = { + provider: 'NFS', + zoneid: zoneid, + url: url + }; + + $.ajax({ + url: createURL('createCacheStore'), + data: nfsCacheData, + success: function(json) { + //do nothing + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + } + else if(args.data.provider == 'Swift') { + $.extend(data, { + provider: args.data.provider, + url: args.data.url + }); + + var index = 0; + if(args.data.account != null && args.data.account.length > 0){ + data['details[' + index.toString() + '].key'] = 'account'; + data['details[' + index.toString() + '].value'] = args.data.account; + index++; + } + if(args.data.username != null && args.data.username.length > 0){ + data['details[' + index.toString() + '].key'] = 'username'; + data['details[' + index.toString() + '].value'] = args.data.username; + index++; + } + if(args.data.key != null && args.data.key.length > 0){ + data['details[' + index.toString() + '].key'] = 'key'; + data['details[' + index.toString() + '].value'] = args.data.key; + index++; + } + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + havingSwift = true; + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + }, + + notification: { + poll: function(args) { + args.complete({ + actionFilter: secondarystorageActionfilter + }); + } + }, + + messages: { + notification: function(args) { + return 'label.add.secondary.storage'; + } + } } - else if(args.data.provider == 'Swift') { - $.extend(data, { - provider: args.data.provider, - url: args.data.url - }); - - var index = 0; - if(args.data.account != null && args.data.account.length > 0){ - data['details[' + index.toString() + '].key'] = 'account'; - data['details[' + index.toString() + '].value'] = args.data.account; - index++; - } - if(args.data.username != null && args.data.username.length > 0){ - data['details[' + index.toString() + '].key'] = 'username'; - data['details[' + index.toString() + '].value'] = args.data.username; - index++; - } - if(args.data.key != null && args.data.key.length > 0){ - data['details[' + index.toString() + '].key'] = 'key'; - data['details[' + index.toString() + '].value'] = args.data.key; - index++; - } - $.ajax({ - url: createURL('addImageStore'), - data: data, - success: function(json) { - havingSwift = true; - var item = json.addimagestoreresponse.secondarystorage; - args.response.success({ - data:item + }, + + detailView: { + name: 'Secondary storage details', + isMaximized: true, + actions: { + remove: { + label: 'label.action.delete.secondary.storage' , + messages: { + confirm: function(args) { + return 'message.action.delete.secondary.storage'; + }, + notification: function(args) { + return 'label.action.delete.secondary.storage'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteImageStore&id=" + args.context.secondarystorages[0].id), + dataType: "json", + async: true, + success: function(json) { + args.response.success(); + } }); }, - error: function(json) { - args.response.error(parseXMLHttpResponse(json)); + notification: { + poll: function(args) { args.complete({ data: { resourcestate: 'Destroyed' } }); } } - }); - } - }, + } - notification: { - poll: function(args) { - args.complete({ - actionFilter: secondarystorageActionfilter - }); - } - }, + }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + url: { label: 'label.url' }, + providername: { label: 'Provider' }, + scope: { label: 'label.scope' }, + zonename: { label: 'label.zone' }, + details: { + label: 'label.details', + converter: function(array1) { + var string1 = ''; + if(array1 != null) { + for(var i = 0; i < array1.length; i++) { + if(i > 0) + string1 += ', '; - messages: { - notification: function(args) { - return 'label.add.secondary.storage'; + string1 += array1[i].name + ': ' + array1[i].value; + } + } + return string1; + } + }, + id: { label: 'label.id' } + } + ], + + dataProvider: function(args) { + $.ajax({ + url: createURL("listImageStores&id=" + args.context.secondarystorages[0].id), + dataType: "json", + async: true, + success: function(json) { + var item = json.listimagestoreresponse.imagestore[0]; + args.response.success({ + actionFilter: secondarystorageActionfilter, + data:item + }); + } + }); + } + } + + // Granular settings for storage pool for secondary storage is not required + /* settings: { + title: 'label.menu.global.settings', + custom: cloudStack.uiCustom.granularSettings({ + dataProvider: function(args) { + args.response.success({ + data: [ + { name: 'config.param.1', value: 1 }, + { name: 'config.param.2', value: 2 } + ] + }); + }, + actions: { + edit: function(args) { + // call updateStorageLevelParameters + args.response.success(); + } + } + }) + } */ } } } }, + imageStores: { + type: 'select', + title: 'Image stores', + listView: { + id: 'secondarystorages', + section: 'seconary-storage', + fields: { + name: { label: 'label.name' }, + url: { label: 'label.url' }, + providername: { label: 'Provider' } + }, - detailView: { - name: 'Secondary storage details', - isMaximized: true, - actions: { - remove: { - label: 'label.action.delete.secondary.storage' , - messages: { - confirm: function(args) { - return 'message.action.delete.secondary.storage'; - }, - notification: function(args) { - return 'label.action.delete.secondary.storage'; - } - }, - action: function(args) { - $.ajax({ - url: createURL("deleteImageStore&id=" + args.context.secondarystorages[0].id), - dataType: "json", - async: true, - success: function(json) { - args.response.success(); + dataProvider: function(args) { + var array1 = []; + if(args.filterBy != null) { + if(args.filterBy.search != null && args.filterBy.search.by != null && args.filterBy.search.value != null) { + switch(args.filterBy.search.by) { + case "name": + if(args.filterBy.search.value.length > 0) + array1.push("&keyword=" + args.filterBy.search.value); + break; } - }); - }, - notification: { - poll: function(args) { args.complete({ data: { resourcestate: 'Destroyed' } }); } - } - } - - }, - tabs: { - details: { - title: 'label.details', - fields: [ - { - name: { label: 'label.name' } - }, - { - url: { label: 'label.url' }, - providername: { label: 'Provider' }, - scope: { label: 'label.scope' }, - zonename: { label: 'label.zone' }, - details: { - label: 'label.details', - converter: function(array1) { - var string1 = ''; - if(array1 != null) { - for(var i = 0; i < array1.length; i++) { - if(i > 0) - string1 += ', '; - - string1 += array1[i].name + ': ' + array1[i].value; - } - } - return string1; - } - }, - id: { label: 'label.id' } } - ], - - dataProvider: function(args) { - $.ajax({ - url: createURL("listImageStores&id=" + args.context.secondarystorages[0].id), - dataType: "json", - async: true, - success: function(json) { - var item = json.listimagestoreresponse.imagestore[0]; - args.response.success({ - actionFilter: secondarystorageActionfilter, - data:item - }); - } - }); } - } - - // Granular settings for storage pool for secondary storage is not required - /* settings: { - title: 'label.menu.global.settings', - custom: cloudStack.uiCustom.granularSettings({ - dataProvider: function(args) { + array1.push("&zoneid=" + args.context.zones[0].id); + + $.ajax({ + url: createURL("listImageStores&page=" + args.page + "&pagesize=" + pageSize + array1.join("")), + dataType: "json", + async: true, + success: function(json) { + var items = json.listimagestoreresponse.imagestore; args.response.success({ - data: [ - { name: 'config.param.1', value: 1 }, - { name: 'config.param.2', value: 2 } - ] + actionFilter: secondarystorageActionfilter, + data:items }); + } + }); + }, + + actions: { + add: { + label: 'label.add.secondary.storage', + + createForm: { + title: 'label.add.secondary.storage', + + fields: { + name: { label: 'label.name' }, + provider: { + label: 'Provider', + select: function(args){ + $.ajax({ + url: createURL('listStorageProviders'), + data: { + type: 'image' + }, + success: function(json){ + var objs = json.liststorageprovidersresponse.dataStoreProvider; + var items = []; + if(objs != null) { + for(var i = 0; i < objs.length; i++){ + if(objs[i].name == 'NFS') + items.unshift({id: objs[i].name, description: objs[i].name}); + else + items.push({id: objs[i].name, description: objs[i].name}); + } + } + args.response.success({ + data: items + }); + + args.$select.change(function() { + var $form = $(this).closest('form'); + if($(this).val() == "NFS") { + //NFS + $form.find('.form-item[rel=zoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=path]').css('display', 'inline-block'); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if ($(this).val() == "S3") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').css('display', 'inline-block'); + $form.find('.form-item[rel=secretkey]').css('display', 'inline-block'); + $form.find('.form-item[rel=bucket]').css('display', 'inline-block'); + $form.find('.form-item[rel=endpoint]').css('display', 'inline-block'); + $form.find('.form-item[rel=usehttps]').css('display', 'inline-block'); + $form.find('.form-item[rel=connectiontimeout]').css('display', 'inline-block'); + $form.find('.form-item[rel=maxerrorretry]').css('display', 'inline-block'); + $form.find('.form-item[rel=sockettimeout]').css('display', 'inline-block'); + + $form.find('.form-item[rel=createNfsCache]').find('input').attr('checked','checked'); + $form.find('.form-item[rel=createNfsCache]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheZoneid]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCacheNfsServer]').css('display', 'inline-block'); + $form.find('.form-item[rel=nfsCachePath]').css('display', 'inline-block'); + + + //Swift + $form.find('.form-item[rel=url]').hide(); + $form.find('.form-item[rel=account]').hide(); + $form.find('.form-item[rel=username]').hide(); + $form.find('.form-item[rel=key]').hide(); + } + else if($(this).val() == "Swift") { + //NFS + $form.find('.form-item[rel=zoneid]').hide(); + $form.find('.form-item[rel=nfsServer]').hide(); + $form.find('.form-item[rel=path]').hide(); + + //S3 + $form.find('.form-item[rel=accesskey]').hide(); + $form.find('.form-item[rel=secretkey]').hide(); + $form.find('.form-item[rel=bucket]').hide(); + $form.find('.form-item[rel=endpoint]').hide(); + $form.find('.form-item[rel=usehttps]').hide(); + $form.find('.form-item[rel=connectiontimeout]').hide(); + $form.find('.form-item[rel=maxerrorretry]').hide(); + $form.find('.form-item[rel=sockettimeout]').hide(); + + $form.find('.form-item[rel=createNfsCache]').find('input').removeAttr('checked'); + $form.find('.form-item[rel=createNfsCache]').hide(); + $form.find('.form-item[rel=nfsCacheZoneid]').hide(); + $form.find('.form-item[rel=nfsCacheNfsServer]').hide(); + $form.find('.form-item[rel=nfsCachePath]').hide(); + + //Swift + $form.find('.form-item[rel=url]').css('display', 'inline-block'); + $form.find('.form-item[rel=account]').css('display', 'inline-block'); + $form.find('.form-item[rel=username]').css('display', 'inline-block'); + $form.find('.form-item[rel=key]').css('display', 'inline-block'); + } + }); + + args.$select.change(); + } + }); + } + }, + + + //NFS (begin) + zoneid: { + label: 'Zone', + docID: 'helpSecondaryStorageZone', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone ? json.listzonesresponse.zone : []; + + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } + } + }); + } + }, + nfsServer: { + label: 'label.nfs.server', + docID: 'helpSecondaryStorageNFSServer', + validation: { required: true } + }, + path: { + label: 'label.path', + docID: 'helpSecondaryStoragePath', + validation: { required: true } + }, + //NFS (end) + + + //S3 (begin) + accesskey: { label: 'label.s3.access_key', validation: { required: true } }, + secretkey: { label: 'label.s3.secret_key', validation: { required: true} }, + bucket: { label: 'label.s3.bucket', validation: { required: true} }, + endpoint: { label: 'label.s3.endpoint' }, + usehttps: { + label: 'label.s3.use_https', + isEditable: true, + isBoolean: true, + isChecked: true, + converter:cloudStack.converters.toBooleanText + }, + connectiontimeout: { label: 'label.s3.connection_timeout' }, + maxerrorretry: { label: 'label.s3.max_error_retry' }, + sockettimeout: { label: 'label.s3.socket_timeout' }, + + createNfsCache: { + label: 'Create NFS Cache Storage', + isBoolean: true, + isChecked: true + }, + nfsCacheZoneid: { + dependsOn: 'createNfsCache', + label: 'Zone', + validation: { required: true }, + select: function(args) { + $.ajax({ + url: createURL('listZones'), + data: { + listAll: true + }, + success: function(json) { + var zones = json.listzonesresponse.zone; + + if(zones != null){ //$.map(items, fn) - items can not be null + args.response.success({ + data: $.map(zones, function(zone) { + return { + id: zone.id, + description: zone.name + }; + }) + }); + } + else { + args.response.success({data: null}); + } + } + }); + } + }, + nfsCacheNfsServer: { + dependsOn: 'createNfsCache', + label: 'label.nfs.server', + validation: { required: true } + }, + nfsCachePath: { + dependsOn: 'createNfsCache', + label: 'label.path', + validation: { required: true } + }, + //S3 (end) + + + //Swift (begin) + url: { label: 'label.url', validation: { required: true } }, + account: { label: 'label.account' }, + username: { label: 'label.username' }, + key: { label: 'label.key' } + //Swift (end) + } }, - actions: { - edit: function(args) { - // call updateStorageLevelParameters - args.response.success(); + + action: function(args) { + var data = {}; + if(args.data.name != null && args.data.name.length > 0) { + $.extend(data, { + name: args.data.name + }); + } + + if(args.data.provider == 'NFS') { + var zoneid = args.data.zoneid; + var nfs_server = args.data.nfsServer; + var path = args.data.path; + var url = nfsURL(nfs_server, path); + + $.extend(data, { + provider: args.data.provider, + zoneid: zoneid, + url: url + }); + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(XMLHttpResponse) { + var errorMsg = parseXMLHttpResponse(XMLHttpResponse); + args.response.error(errorMsg); + } + }); + } + else if(args.data.provider == 'S3') { + $.extend(data, { + provider: args.data.provider, + 'details[0].key': 'accesskey', + 'details[0].value': args.data.accesskey, + 'details[1].key': 'secretkey', + 'details[1].value': args.data.secretkey, + 'details[2].key': 'bucket', + 'details[2].value': args.data.bucket, + 'details[3].key': 'usehttps', + 'details[3].value': (args.data.usehttps != null && args.data.usehttps == 'on' ? 'true' : 'false') + }); + + var index = 4; + if(args.data.endpoint != null && args.data.endpoint.length > 0){ + data['details[' + index.toString() + '].key'] = 'endpoint'; + data['details[' + index.toString() + '].value'] = args.data.endpoint; + index++; + } + if(args.data.connectiontimeout != null && args.data.connectiontimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'connectiontimeout'; + data['details[' + index.toString() + '].value'] = args.data.connectiontimeout; + index++; + } + if(args.data.maxerrorretry != null && args.data.maxerrorretry.length > 0){ + data['details[' + index.toString() + '].key'] = 'maxerrorretry'; + data['details[' + index.toString() + '].value'] = args.data.maxerrorretry; + index++; + } + if(args.data.sockettimeout != null && args.data.sockettimeout.length > 0){ + data['details[' + index.toString() + '].key'] = 'sockettimeout'; + data['details[' + index.toString() + '].value'] = args.data.sockettimeout; + index++; + } + + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + havingS3 = true; + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + + if(args.data.createNfsCache == 'on') { + var zoneid = args.data.nfsCacheZoneid; + var nfs_server = args.data.nfsCacheNfsServer; + var path = args.data.nfsCachePath; + var url = nfsURL(nfs_server, path); + + var nfsCacheData = { + provider: 'NFS', + zoneid: zoneid, + url: url + }; + + $.ajax({ + url: createURL('createCacheStore'), + data: nfsCacheData, + success: function(json) { + //do nothing + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + } + else if(args.data.provider == 'Swift') { + $.extend(data, { + provider: args.data.provider, + url: args.data.url + }); + + var index = 0; + if(args.data.account != null && args.data.account.length > 0){ + data['details[' + index.toString() + '].key'] = 'account'; + data['details[' + index.toString() + '].value'] = args.data.account; + index++; + } + if(args.data.username != null && args.data.username.length > 0){ + data['details[' + index.toString() + '].key'] = 'username'; + data['details[' + index.toString() + '].value'] = args.data.username; + index++; + } + if(args.data.key != null && args.data.key.length > 0){ + data['details[' + index.toString() + '].key'] = 'key'; + data['details[' + index.toString() + '].value'] = args.data.key; + index++; + } + $.ajax({ + url: createURL('addImageStore'), + data: data, + success: function(json) { + havingSwift = true; + var item = json.addimagestoreresponse.secondarystorage; + args.response.success({ + data:item + }); + }, + error: function(json) { + args.response.error(parseXMLHttpResponse(json)); + } + }); + } + }, + + notification: { + poll: function(args) { + args.complete({ + actionFilter: secondarystorageActionfilter + }); + } + }, + + messages: { + notification: function(args) { + return 'label.add.secondary.storage'; } } - }) - } */ + } + }, + + detailView: { + name: 'Secondary storage details', + isMaximized: true, + actions: { + remove: { + label: 'label.action.delete.secondary.storage' , + messages: { + confirm: function(args) { + return 'message.action.delete.secondary.storage'; + }, + notification: function(args) { + return 'label.action.delete.secondary.storage'; + } + }, + action: function(args) { + $.ajax({ + url: createURL("deleteImageStore&id=" + args.context.secondarystorages[0].id), + dataType: "json", + async: true, + success: function(json) { + args.response.success(); + } + }); + }, + notification: { + poll: function(args) { args.complete({ data: { resourcestate: 'Destroyed' } }); } + } + } + + }, + tabs: { + details: { + title: 'label.details', + fields: [ + { + name: { label: 'label.name' } + }, + { + url: { label: 'label.url' }, + providername: { label: 'Provider' }, + scope: { label: 'label.scope' }, + zonename: { label: 'label.zone' }, + details: { + label: 'label.details', + converter: function(array1) { + var string1 = ''; + if(array1 != null) { + for(var i = 0; i < array1.length; i++) { + if(i > 0) + string1 += ', '; + + string1 += array1[i].name + ': ' + array1[i].value; + } + } + return string1; + } + }, + id: { label: 'label.id' } + } + ], + + dataProvider: function(args) { + $.ajax({ + url: createURL("listImageStores&id=" + args.context.secondarystorages[0].id), + dataType: "json", + async: true, + success: function(json) { + var item = json.listimagestoreresponse.imagestore[0]; + args.response.success({ + actionFilter: secondarystorageActionfilter, + data:item + }); + } + }); + } + } + + // Granular settings for storage pool for secondary storage is not required + /* settings: { + title: 'label.menu.global.settings', + custom: cloudStack.uiCustom.granularSettings({ + dataProvider: function(args) { + args.response.success({ + data: [ + { name: 'config.param.1', value: 1 }, + { name: 'config.param.2', value: 2 } + ] + }); + }, + actions: { + edit: function(args) { + // call updateStorageLevelParameters + args.response.success(); + } + } + }) + } */ + } + } } } } From bd84005b4ee7524d5a7f2b893f77474da421dbea Mon Sep 17 00:00:00 2001 From: Brian Federle Date: Wed, 19 Jun 2013 12:24:58 -0700 Subject: [PATCH 302/303] Infrastructure UI: Fix list views with sub-sections --- ui/scripts/ui-custom/physicalResources.js | 3 ++- ui/scripts/ui-custom/zoneChart.js | 9 ++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/scripts/ui-custom/physicalResources.js b/ui/scripts/ui-custom/physicalResources.js index 69c0295c08d..65b87e4415a 100644 --- a/ui/scripts/ui-custom/physicalResources.js +++ b/ui/scripts/ui-custom/physicalResources.js @@ -18,8 +18,9 @@ cloudStack.uiCustom.physicalResources = function(args) { var listView = function(targetID) { var target = args.sections.physicalResources.listView[targetID]; + var listViewArgs = $.isFunction(target) ? target() : target; - return $('

').listView({ listView: $.isFunction(target) ? target() : target }); + return $('
').listView(listViewArgs.listView ? listViewArgs : { listView: listViewArgs }); }; var $dashboard = $('#template').find('.system-dashboard-view').clone(); var getData = function() { diff --git a/ui/scripts/ui-custom/zoneChart.js b/ui/scripts/ui-custom/zoneChart.js index 12ba6aa6edc..fcfc7669334 100644 --- a/ui/scripts/ui-custom/zoneChart.js +++ b/ui/scripts/ui-custom/zoneChart.js @@ -58,12 +58,11 @@ listView: function(targetID, context) { return function(args) { var $elem = args.$panel; - var listViewArgs = cloudStack.sections.system.subsections[targetID].listView; + var listView = cloudStack.sections.system.subsections[targetID]; - $elem.listView({ - context: context, - listView: listViewArgs - }); + $elem.listView($.extend(true, {}, listView, { + context: context + })); }; }, From f0ebb0596dd26c7156e96ce2fedb25bca2af75f1 Mon Sep 17 00:00:00 2001 From: Min Chen Date: Wed, 19 Jun 2013 16:50:27 -0700 Subject: [PATCH 303/303] CLOUDSTACK-3027:Object_Store_Refactor - Uploaded template S3 content-type is not appropriate --- .../cloud/storage/template/S3TemplateDownloader.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/src/com/cloud/storage/template/S3TemplateDownloader.java b/core/src/com/cloud/storage/template/S3TemplateDownloader.java index 7763423a4a0..340e0dba868 100644 --- a/core/src/com/cloud/storage/template/S3TemplateDownloader.java +++ b/core/src/com/cloud/storage/template/S3TemplateDownloader.java @@ -209,6 +209,13 @@ public class S3TemplateDownloader implements TemplateDownloader { remoteSize = maxTemplateSizeInByte; } + // get content type + String contentType = null; + Header contentTypeHeader = request.getResponseHeader("Content-Type"); + if ( contentTypeHeader != null ){ + contentType = contentTypeHeader.getValue(); + } + InputStream in = !chunked ? new BufferedInputStream(request.getResponseBodyAsStream()) : new ChunkedInputStream(request.getResponseBodyAsStream()); @@ -225,6 +232,9 @@ public class S3TemplateDownloader implements TemplateDownloader { // download using S3 API ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(remoteSize); + if ( contentType != null ){ + metadata.setContentType(contentType); + } PutObjectRequest putObjectRequest = new PutObjectRequest(s3.getBucketName(), s3Key, in, metadata); // check if RRS is enabled if (s3.getEnableRRS()){